Sign in to follow this  

c# sockets multi client/server implementation

This topic is 3305 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I will be implementing a multi client/server game structure that uses TCP. When the connection of a client is established with the server and the exchange was done, can I just retain the connection until the client initiates to disconnect? Or just disconnect whenever a request/response was finished then establish a new connection again if it is needed? I am just concerned that if the connection will be continous it may be not a good choice because of network issues (bandwidth,security or anything) or client machine issues (memory,local resource or anything) How does multi player games are implemented with regards to connection? I hope anyone can help me on this.

Share this post


Link to post
Share on other sites
For most games you will likely maintain a client connection for the time the client interacts with the server until disconnect is detected. This seems better than per-request connection handling like a web server.
Remember that you need to associate state data specific to each connected client.
While that can be worked around (session id), you will also need to send data to a client when he did not even request anything (e.g. when other players move).

You should however time out and close connections which are idle for too long (i.e. you do not receive anything from a client for some time). For this to work you must require the client to send alive/ping messages in given intervals whenever they do not send any other action for a given time.

Share this post


Link to post
Share on other sites
Quote:
Original post by jmp97
For most games you will likely maintain a client connection for the time the client interacts with the server until disconnect is detected. This seems better than per-request connection handling like a web server.
Remember that you need to associate state data specific to each connected client.
While that can be worked around (session id), you will also need to send data to a client when he did not even request anything (e.g. when other players move).

You should however time out and close connections which are idle for too long (i.e. you do not receive anything from a client for some time). For this to work you must require the client to send alive/ping messages in given intervals whenever they do not send any other action for a given time.


Thanks for the reply.
If that was the case, wouldn't it take too much resources on the server? And how about the network traffic,does it affect the connection of others? (Making the response for a player action to be slower)

Does it mean that I need to have a 1 thread per client?

TIA

Share this post


Link to post
Share on other sites
It's no need to spawn the new thread for the new client, you can do all of that in one thread that handle all the client data. But it's some kind of pros-and-cons here between the two.

If you spawn the thread, it's clean and nice to do but with the limitation of thread can be spawned on such system (game server), and it will comsume more memory.
If you do it all in one thread, the time-sharing to give for all clients to update their stuff is concerned, and the algorithm there should be careful done.

Nevertheless if the game is not too large, I prefer using spawn the new threads due to it's likely to be implemented in short time.

Share this post


Link to post
Share on other sites
Quote:
Original post by haxpor
It's no need to spawn the new thread for the new client, you can do all of that in one thread that handle all the client data. But it's some kind of pros-and-cons here between the two.

If you spawn the thread, it's clean and nice to do but with the limitation of thread can be spawned on such system (game server), and it will comsume more memory.
If you do it all in one thread, the time-sharing to give for all clients to update their stuff is concerned, and the algorithm there should be careful done.

Nevertheless if the game is not too large, I prefer using spawn the new threads due to it's likely to be implemented in short time.


Ok thanks, that clarifies something.
But how about the network traffic? If there are too many clients(may be 200) playing(connected) at the same time,will the reponse' transfer rate will be affected? do i expect a slower response time here?

TIA

Share this post


Link to post
Share on other sites
hi Kylotan

for my clients, it will have two kinds(both in same machine):
1)gameplay client - this client sends the player's move towards the game. it usually have information size that may range from 1mb and below and frequency is very high like every 500ms

2)normal client - this clients are the one doing some game update(graphics/sound)and other. File size may range from 100mb or more. Depends on the file but may be too large. Frequency may be every 10min

these clients may run simultaneously.
the machines may range from 20 upto 200(as of the moment) or maybe more..

Hope I clarified some details.

TIA

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
Are you saying you want a client to sometimes send 2 megabytes a second, or 100 megabytes every 10 minutes?


sorry, actually I just exaggerated the values for a maximum rough estimate,but honestly I have not considered the size of the message to send...it is really my first time to do network game programming and I am not very sure of how large can the data would go..

Share this post


Link to post
Share on other sites
You need to get a handle on how much data you will need, first. You can't do capacity planning without it.

Given the fixed size buffers in the kernel, both for UDP and TCP, the maximum amount of data that a client can send to you equals the rate at which you read data from the client. If you make sure to not read more than, say, 3 kB/s from each client, at the application layer, then the buffering (for UDP) and windowing (for TCP) will make sure that not more than that is actually successfully delivered to you. Clients trying to send more will either see a lot of packet loss and latency (UDP), or will see their client-side send queues and latencies grow possibly unbounded (TCP).

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
You need to get a handle on how much data you will need, first. You can't do capacity planning without it.

Given the fixed size buffers in the kernel, both for UDP and TCP, the maximum amount of data that a client can send to you equals the rate at which you read data from the client. If you make sure to not read more than, say, 3 kB/s from each client, at the application layer, then the buffering (for UDP) and windowing (for TCP) will make sure that not more than that is actually successfully delivered to you. Clients trying to send more will either see a lot of packet loss and latency (UDP), or will see their client-side send queues and latencies grow possibly unbounded (TCP).


Ok I got it,thanks.

As of now the maximum size that I can have is 50kb of data. My 200 clients may simultaneously connect then send&read this. It may happen infinitely until the client trigger an end game or disconnect. My question is,what would be the best for my server:
1) keep the alive connection until client terminates?
2) client connects to the server every time it will need to send/receive a 50kb of data?

I really appreciate your replies

TIA

Share this post


Link to post
Share on other sites
I guess that would depend on how frequently data is exchanged between client and server. If, after the 50kb have been sent out, there is no more communication between server and client for quite some time (say a minute or so) then a connect-per-request can be a possibility.
But since you spoke of a gaming system and clients moving around I would assume that data exchanges happen frequently and are also triggered asynchronously (not only request-response) which would seem to call for maintaining the connection.

If bandwidth concerns you, that will not be solved by disconnecting the clients after exchange as far as I can see. Your software layer should handle how much data is sent to and read from the clients. As hplus0603 mentioned, if the server reads from your client connections you determine how much you are going to allow each client to send in at a time - e.g. just read up to n kb per iteration.

Why do you think you need to send so much data for positional packets? Maybe you can tell us what kind of game it is (2D / 3D) and which elements other than a change of position are involved when moving.

Share this post


Link to post
Share on other sites
Connection of a TCP socket requires one round-trip (i.e. the client sends a packet, the server responds). This happens a low level when you call the connect function.

So that would mean if you connect, send data, disconnect over and over, you're essentially doubling the round-trip time to the server. So a 50ms ping becomes a 100ms ping.

Keeping the connection open doesn't affect the bandwidth available to the server. The bandwidth is affected by the amount of simultaneous data that is actually being transferred. There's a little bit of extra memory for each open connection required on the server, but it's fairly minimal.

So my recommendation would be to keep the connection open for as long as you need to...

Share this post


Link to post
Share on other sites
it is a 2D game as of now.
then later will be implementing it as 3D.

what I am creating as of now is basically just a common structure on how to send player actions to server and receive the result of that action back. About the elements I dont have any idea yet but the Change of position is the only element that could be the largest of them all.


Thank you to all of you that have replied.

It really helped me a lot.

I think that having the connection alive will be the answer for me.

Share this post


Link to post
Share on other sites
If it's a session, where you keep state per connection, then you should not be creating/destroying sessions all the time.

If it's a request/response system like HTTP, where the client will ask for some data and then go away, then you should be using HTTP.

Also, if you need to push data to clients (say, world state updates or other clients' chat code), then you want to use a persistent session/connection, rather than a request system.

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
If it's a session, where you keep state per connection, then you should not be creating/destroying sessions all the time.

If it's a request/response system like HTTP, where the client will ask for some data and then go away, then you should be using HTTP.

Also, if you need to push data to clients (say, world state updates or other clients' chat code), then you want to use a persistent session/connection, rather than a request system.


Thank you.
That's what I am looking for.

Ok, I will keep that in mind.

Share this post


Link to post
Share on other sites
Quote:
Original post by hplus0603
If it's a session, where you keep state per connection, then you should not be creating/destroying sessions all the time.

If it's a request/response system like HTTP, where the client will ask for some data and then go away, then you should be using HTTP.

Also, if you need to push data to clients (say, world state updates or other clients' chat code), then you want to use a persistent session/connection, rather than a request system.


Btw, just want to ask some follow up.
Can a HTTP handle a session? I mean having a multiple request/response in a form of HTTP,is it possible?

I want to try that using the C#.NET HTTPListener,but have not found any samples like that.

Share this post


Link to post
Share on other sites
HTTP is not designed for sessions; it's a request-response protocol.

Obviously the Web required some concept of a session when using HTTP, so they use cookies - small pieces of data that essentially allow a client to tell a server "hey, this request is from the same guy that sent that other request", thus permitting the server to maintain some sort of state associated with it.

But all that is a bit of a hack compared to just using a connection-oriented protocol and storing the state directly with the connection.

If you're sending a constant stream of requests and expecting to receive a constant stream of replies back, then HTTP is probably the wrong protocol for you. Most games will roll their own protocol on top of TCP or UDP for their specific purpose.

[Edited by - Kylotan on November 21, 2008 8:08:48 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
HTTP is not designed for sessions; it's a request-response protocol.

Obviously the Web required some concept of a session when using HTTP, so they use cookies - small pieces of data that essentially allow a client to tell a server "hey, this request is from the same guy that sent that other request", thus permitting the server to maintain some sort of state associated with it.

But all that is a bit of a hack compared to just using a connection-oriented protocol and storing the state directly with the connection.

If you're sending a constant stream of requests and expecting to receive a constant stream of replies back, then HTTP is probably the wrong protocol for you. Most games will roll their own protocol on top of TCP or UDP for their specific purpose.


OK thanks.
That really clarifies a lot.
I think I will concentrate more on using the TCP or UDP

Share this post


Link to post
Share on other sites

This topic is 3305 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this