I would like to do the simple card game which can many people play at the same time, but not only one game, there can ne n games running.

Recently I was learning how to do server-client coding, using TcpListener and TcpClient network services. But the main difference between the past project and the project which I would like to do it, that the past one had ONLY ONE server. In the next one there will be more then just one server to make it work.

So when someone would like to start a new game, the new server thread has to create (and as many new client thread as many people will join to this server). But I am not sure how to explain this well, all I want is how users can start their own "new servers thread". And there servers threads have to come out of one code.

Simple example is a party poker game.

Can anyone point me to the right direction how and where to start, if it s a good idea of using tcpListener, and tcpClient network services, OR there is something else better for such project?

I would really appreaciate it for a fair and decent answer.

Mitja

ReplyQuote

Maybe my understanding of creating such a game is wrong. There always HAS to be only one server, so only TcpListener. Thats becuase I have only one IP, on which clients can connect.

But how to create New games - what are New games? They cannot be Servers and can either cannot be Clients (clients only connect to the created game). This is something I cannot figure out.

Or the same example is MSN. MSN is one Server. So what are chat-rooms? I can talk with plenty users at the same time. How to define these created chat-rooms?

I'm sorry that I cannot help you technically coz i just lost touch with C# but I could give some ideas
logically.

Single server (i mean the clones too with same port) may not fit in this situation. "Multiple servers" concept
would fit in this situation well.

Use a centralized database which can be accessed by all clients. Use one computer system as server.
Start the session by creating a server thread give it a session/game name
Store the
1) session/game name
2) the server port
3) IP (if necessary)
4) activated (a boolean value, will be explained down)

when a client connects, show the list of games/sessions (only one record available at server startup)
and ask them the session they want to connect.
If they select an existing game use the session's ip and port (stored in the database) to connect the server
from the client system
If the client wants to create a new session/game get the new game/session name from the client
save the details to the database
Use a timer to see whether the activated column(of the newly created session/game) in the database is set
to true
when it becomes true use the record's ip's (of the newly created session/game) and port to connect

At the server side
use timer to see whether any records in the database that are not yet activated
if there exists a record
then create a new server instance assign it a different port no and start the server to listen for connections
in the new port (hope it works with c#. Ive tried the same technique in VB 6.0 for the chat room concept
that you have asked.
In my program i used different port no for different groups.
so the messages of a group will be sent only to the members belong to the group
)
update the database with the new port no.
Make the activated field to 'yes'

If you are choosing this technique make sure the firewall doesnt interfere with your program
It all relies on how you create port no. and how you give the exceptions in firewall

Edited 6 Years Ago by samsylvestertty: n/a

samsylvestertty:
So, for every new session (new game) started, I need a new port, am I right?
And, is DB really necessary? I think it would go without it.
Were you using tscListener and tcpClient for this kind of game?

Just a note: I would like to have only ONE port opened. Not more. So one port, and the clients will be guided by some parameters, who is in which room. How is this possible to do it?

You'll need to set up a message format with some form of code to indicate what type of message it is. If you look up a messaging protocol, you'll see they use the first few bytes of each message to tell the server what they are trying to do. So you would need messages for starting a new game, joining a game, making a move in the game, leaving a game, chatting (if you want to allow that), etc.

Just a note: I would like to have only ONE port opened. Not more. So one port, and the clients will be guided by some parameters, who is in which room. How is this possible to do it?

To my knowledge this is possible(don know how far it is applicable to C#)

Ill try to explain in VB
Check whether it would work in C#

In Visual Basic the tcpsocket is simply a control (control)
Handling the socket is very easy by manipulating the socket object's functions and events
Here the cloning is implemented by control array (of the winsock control)

Have a Dictionary Variable

Use the client's game session name as key
Store all the clone indexes(control array) that are initiated for a specific game session

when a message comes from a client (a move in the game)

search for the server's (a server that receives the message from the client) index in the dictionary.

when it finds an entry get all the other server's indexes that are related to that game/session. send the message(a move in the game) using the servers(related to the game/session) to the clients that are connected to it.

this would solve the multi-port problem

I'm sure this works in VB 6.0.

I know the explanation would confuse you a bit if you are new to VB 6.0 or to control arrays. Ill write and give the code(in VB) if needed. This would make you understand a little more.

I know that C# does not have control arrays.

When comparing to C#
VB Socket Programming is Very easy.
you can use the socket dll in C# (for socket programming alone) that is available in every windows xp system (if not can be downloaded).

OCX NAME: winsock.dll

All the best..

Edited 6 Years Ago by samsylvestertty: n/a

Hi there, the solution is actually the same as one for a normal client/server interaction.

When you start your server, you bind your TcpListner to a port and listen for connections.

When you get a connection, through Accept, you also receive a new socket (which goes to the client), your server connection then resets and starts listening again. So you only need to listen on the single port you use for the server.

Once you have your client socket, this is when you start interacting with the server code. (The server socket is there just to listen for connections not take commands)

When the clients want to say, join a chat room, they will send you a command. You need to check what commands come through the socket and perform the correct action in code.

Taking the example of a chatroom, ClientA and ClientB connect to the server socket. But they are not directly connected to each other as they have seperate sockets in the server program.

ClientA clicks to join ChatroomA and sends the command along the socket to the server. The server then updates, lets say for example, a list in the program that contains the ID of each client in the chatroom. ClientB also joins the chatroom and the program updates the server side list again. Note, ClientA and ClientB are *still* not connected to each other.

ClientA sends a message to the chatroom and the server receives it and understands it's a message for the chatroom. The server application then checks the list of ID's for who is in the chatroom. It knows that ClientA and ClientB are in the chatroom and sends the message down each of their sockets with the "this is a message" command and the message itself. ClientA and ClientB then both update their chatview screens with the message. ClientA and ClientB never actually connected to each other, the server acts like a man-in-the-middle.

Before you make a multiplayer card game. Maybe you should try making the chatroom server first? It would give you a good grasp of what is required and how it works.

samsylvestertty:
if you have any example, it would be really nice.
thx in advance.
Mitja

Check This code. I hope you would understand

Dim dServers As New Dictionary '//Collection of group names and their respective server clones
Dim nCurrentClone As Integer '//Gets the recent clone

Private Sub Form_Load()
    '//Control array
    '//I've loaded only the first server at design time
    wnSample(0).LocalPort = 2106 '//Assigning the server a port no
    wnSample(0).Listen '//Server starts listening
    nCurrentClone = 0 '//The first clone's index is 0
End Sub

'//Event fired when client requests a connection
Private Sub wnSample_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    wnSample(Index).Close '//Close the server (traditional way don know y)
    wnSample(Index).Accept requestID  '//Accept the connection
    '//Load the server clone
    '//Since this is a control array all the properties
    '//of the first clone will be inherited like port no
    Load wnSample(nCurrentClone + 1)
    wnSample(ncurrent + 1).Listen
    nCurrentClone = nCurrentClone + 1
End Sub

'Event Fired when data comes from the client
Private Sub wnSample_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    Dim sMessage As String
    wnSample(Index).GetData sMessage 'Retrieve the message
    'The message needs to be little formatted
    'The client's message is in the following format
    '<<GAME_NAME>><@><<SOMEMESSAGE>>
    'where <@> is a separator
    'For ex.
    'Game_Session_1<@>Ace_Spade (a card no is card or _
    'any message that you want to send to other clients of _
    'the same group) now
    
    
    SendGroupMessage SetGroup(Index, Split(sMessage, "<@>")(0)), Split(sMessage, "<@>")(1)
End Sub

'//function used to create groups, associates server clone to a group
Private Function SetGroup(nCloneNo As Integer, sGroupName As String) As String
    '//Check whether the game already exists
    If dServers.Exists(sGroupName) Then
        '//If ther game_session name is available already
        '//Check whether the server clone index is available in the specified group name
        If DoesCloneExist(nCloneNo, dServers(sGroupName)) = False Then
            '//New client is joining the group - sGroupName
            If Trim(dServers(sGroupName)) = "" Then
                dServers(sGroupName) = "<@>" & nCloneNo & "<@>"
            Else
                dServers(sGroupName) = dServers(sGroupName) & nCloneNo & "<@>"
            End If
        End If
    Else
        '//Game/Session not available
        dServers.Add sGroupName, "<@>" & nCloneNo & "<@>"
    End If
    SetGroup = sGroupName
End Function

'//Function to Check whether a clone exists in a group
Private Function DoesCloneExist(nCloneNo As Integer, sCloneCloud As String) As Boolean
    Dim i As Integer
    '//sCloneCloud - a collection of server indices that belong to a same group(DICTIONARY KEY)
    'Example:
    '/***************************************************
    'DICTIONARY_KEY(GROUPNAME)        DICTIONARY_VALUE(CLONE_IDS)
    'GROUP_1                            <@>1<@>3<@>
    'means server clones 1, 3 belong to group GROUP_1
    '****************************************************/
    If Trim(sCloneCloud) = "" Then
        DoesCloneExist = False
    Else
        DoesCloneExist = InStr(1, sCloneCloud, "<@>" & nCloneNo & "<@>") > 0
    End If
End Function

'//Function used to send message to all client of a specified group
Private Function SendGroupMessage(sGroupName As String, sMsg As String) As Boolean
    '//Error handling ofcourse not reliable as C#'s
    On Error GoTo NoSending
    Dim i As Integer
    '/*Used to store the _
    'server indexes that belong to this group*/
    Dim sGroupMembers() As String
    '/*This gives all _
    'the servers of the group and <@> is the separator */
    sGroupMembers = Split(dServers(sGroupName), "<@>")
    For i = 0 To UBound(sGroupMembers) 'iterate thro the array
        '/* Send message using the servers _
        'this makes all the clients of _
        'of a particular group to receive the _
        'same message. The smsg can contain _
        'the sender information, the move that he made etc. etc.*/
        wnSample(sGroupMembers(i)).SendData sMsg
    Next
    SendGroupMessage = True
    Exit Function
NoSending:
    SendGroupMessage = False
End Function


'/****************************************************************** _
'* THIS IS FULLY WRITTEN IN VB _
'* I HOPE THIS WORKS. BUT I HAVE NOT TRIED RUNNING COZ THE _
'* CLIENT SIDE IS NOT IMPLEMENTED _
'* IF YOU WANT TO GET THIS FUNCTIONALITY _
'* USE THE WINSOCK.DLL AND TRY _
'* I'VE NOT TESTED THIS IN C# BUT SOON ILL TRY _
'* _
'* THE MAIN AIM OF WRITING THIS SMALL PROGRAM IS TO MAKE YOU _
'* UNDERSTAND MY IDEA ABOUT MULTI ROOM / SESSION IN SOCKET PROGRAMMING _
'* IF YOU HAVE ANY COMMENTS (FOR / AGAINST) PLS LET ME KNOW. _
'* TNKS. _
'* THIS PROGRAM WONT WORK ACROSS INTERNET(ALSO I HAVE NOT TRIED). CAN BE _
'* USED WITHIN LAN _
'**********************************************************************/

Edited 6 Years Ago by samsylvestertty: n/a

Check This code. I hope you would understand

Dim dServers As New Dictionary '//Collection of group names and their respective server clones
Dim nCurrentClone As Integer '//Gets the recent clone

Private Sub Form_Load()
    '//Control array
    '//I've loaded only the first server at design time
    wnSample(0).LocalPort = 2106 '//Assigning the server a port no
    wnSample(0).Listen '//Server starts listening
    nCurrentClone = 0 '//The first clone's index is 0
End Sub

'//Event fired when client requests a connection
Private Sub wnSample_ConnectionRequest(Index As Integer, ByVal requestID As Long)
    wnSample(Index).Close '//Close the server (traditional way don know y)
    wnSample(Index).Accept requestID  '//Accept the connection
    '//Load the server clone
    '//Since this is a control array all the properties
    '//of the first clone will be inherited like port no
    Load wnSample(nCurrentClone + 1)
    wnSample(ncurrent + 1).Listen
    nCurrentClone = nCurrentClone + 1
End Sub

'Event Fired when data comes from the client
Private Sub wnSample_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    Dim sMessage As String
    wnSample(Index).GetData sMessage 'Retrieve the message
    'The message needs to be little formatted
    'The client's message is in the following format
    '<<GAME_NAME>><@><<SOMEMESSAGE>>
    'where <@> is a separator
    'For ex.
    'Game_Session_1<@>Ace_Spade (a card no is card or _
    'any message that you want to send to other clients of _
    'the same group) now
    
    
    SendGroupMessage SetGroup(Index, Split(sMessage, "<@>")(0)), Split(sMessage, "<@>")(1)
End Sub

'//function used to create groups, associates server clone to a group
Private Function SetGroup(nCloneNo As Integer, sGroupName As String) As String
    '//Check whether the game already exists
    If dServers.Exists(sGroupName) Then
        '//If ther game_session name is available already
        '//Check whether the server clone index is available in the specified group name
        If DoesCloneExist(nCloneNo, dServers(sGroupName)) = False Then
            '//New client is joining the group - sGroupName
            If Trim(dServers(sGroupName)) = "" Then
                dServers(sGroupName) = "<@>" & nCloneNo & "<@>"
            Else
                dServers(sGroupName) = dServers(sGroupName) & nCloneNo & "<@>"
            End If
        End If
    Else
        '//Game/Session not available
        dServers.Add sGroupName, "<@>" & nCloneNo & "<@>"
    End If
    SetGroup = sGroupName
End Function

'//Function to Check whether a clone exists in a group
Private Function DoesCloneExist(nCloneNo As Integer, sCloneCloud As String) As Boolean
    Dim i As Integer
    '//sCloneCloud - a collection of server indices that belong to a same group(DICTIONARY KEY)
    'Example:
    '/***************************************************
    'DICTIONARY_KEY(GROUPNAME)        DICTIONARY_VALUE(CLONE_IDS)
    'GROUP_1                            <@>1<@>3<@>
    'means server clones 1, 3 belong to group GROUP_1
    '****************************************************/
    If Trim(sCloneCloud) = "" Then
        DoesCloneExist = False
    Else
        DoesCloneExist = InStr(1, sCloneCloud, "<@>" & nCloneNo & "<@>") > 0
    End If
End Function

'//Function used to send message to all client of a specified group
Private Function SendGroupMessage(sGroupName As String, sMsg As String) As Boolean
    '//Error handling ofcourse not reliable as C#'s
    On Error GoTo NoSending
    Dim i As Integer
    '/*Used to store the _
    'server indexes that belong to this group*/
    Dim sGroupMembers() As String
    '/*This gives all _
    'the servers of the group and <@> is the separator */
    sGroupMembers = Split(dServers(sGroupName), "<@>")
    For i = 0 To UBound(sGroupMembers) 'iterate thro the array
        '/* Send message using the servers _
        'this makes all the clients of _
        'of a particular group to receive the _
        'same message. The smsg can contain _
        'the sender information, the move that he made etc. etc.*/
        wnSample(sGroupMembers(i)).SendData sMsg
    Next
    SendGroupMessage = True
    Exit Function
NoSending:
    SendGroupMessage = False
End Function


'/****************************************************************** _
'* THIS IS FULLY WRITTEN IN VB _
'* I HOPE THIS WORKS. BUT I HAVE NOT TRIED RUNNING COZ THE _
'* CLIENT SIDE IS NOT IMPLEMENTED _
'* IF YOU WANT TO GET THIS FUNCTIONALITY _
'* USE THE WINSOCK.DLL AND TRY _
'* I'VE NOT TESTED THIS IN C# BUT SOON ILL TRY _
'* _
'* THE MAIN AIM OF WRITING THIS SMALL PROGRAM IS TO MAKE YOU _
'* UNDERSTAND MY IDEA ABOUT MULTI ROOM / SESSION IN SOCKET PROGRAMMING _
'* IF YOU HAVE ANY COMMENTS (FOR / AGAINST) PLS LET ME KNOW. _
'* TNKS. _
'* THIS PROGRAM WONT WORK ACROSS INTERNET(ALSO I HAVE NOT TRIED). CAN BE _
'* USED WITHIN LAN _
'**********************************************************************/

In C# you don't need any access to WinSock as .Net has a reference to System.Net.Sockets which will provide everything needed. You should have this in VB.Net too.

This gives you access to TcpClient, TcpListener, UdpClient and the base Socket object.
All these methods allow quick and easy access to networking functionality =)

The majority of the code should really be going on the logic that runs the game servers such as event broadcasting and client registration etc. The easy part is sending and receiving the data ;)

im sorry the Socket dll doesn't work with c#. you can use only the logic Of my program

Edited 6 Years Ago by samsylvestertty: n/a

Thx samsylvestertty, I will check the code.
btw, what is UdpClient for? So far I was only using TcpListener and TcpClient.

Edited 6 Years Ago by Mitja Bonca: n/a

It's a different type of protocol. You shouldn't need to worry about it at the moment, but here's a quick description.

UDP is classed as an "Unrealiable protocol". This is not to say it doesn't work, but more to describe how it handles data transmission. UDP has no handshaking, data integrity checking or packet order checking. It is commonly used as "Fire and Forget". You give a UDP packet a destination and payload and send it on it's way. You then forget about it. There is no "ACK" response or handshake to say it was received. The only way you know it was received is if you receive data back from wherever you just sent it.

TCP is classed as a "reliable" protocol as it includes all the things I stated were missing from UDP.

Ketsuekiame:
I have already done a chat programs, with a server and clients who can login on the server with appropriate ip and port of the server.
Now I have found out, that one of the solution of creating card game is, that when a client who connects to server and wants to start a new game, he then can become a server to all the clients who will join to that new game.
But I am not sure how to code it. I mean the point when the client becomes the server. How this can be made?


If any example possible, even better.

I would advise against the client becoming the server.

The code to do it is pretty simple. Send a command to the client saying "You are a server" or in fact have the client send a message to the server saying "I am a server".

But you still have to make a direct connection from the OTHER clients to your new client-server.

A better way is to have the server act as a proxy, so that when the client says "I want to make a room" the server sets it up in its code somewhere. So when the other clients ask for a list of rooms, the server replies with all the clients who have made a room. The server then sends messages between each other client in the room when they decide to "connect" to it.

Note that this isn't an ACTUAL connection, simply some logic in the server code.

any1 came to this conclusion?

any1 can create game server ?

i want cod C# for create game serve :-s

This article has been dead for over six months. Start a new discussion instead.