Sign in to follow this  

?Socket server?

This topic is 4195 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

Hi there! I am on a quest to create a low-level socket layer for a TCP socket server that I can than use to create ultimate online games. x) I have been reading through whatever I could get my hands on to get the idea of what a socket server should look like. Right now I am trying to make a list of requirements to get started with coding. At the same time there's a bunch of questions and worries that have been amassing during the readings and I would appreciate if some of you guys could help me out with answers. Requirements (please feel free to add your suggestions) r1. Support for a large number of clients ( > 1000 connections). r2. Non-blocking architecture. r3. Handling partial sends r4. Portability (Windows & Unix). Now questions.... q1 In some of the papers I've read, people suggest using one thread per user so that our socket is non-blocking. Is this a realistic approach, taking into consideration r1? Do real world applications that deal with thousands of users use this approach? I am considering using **select** function to achieve multiplexing. Can I just put **select** + some additional code in a separate thread and have it checking users joining and leaving and also reading data from socket when there's data to read? At the same time I want to be able to send data to clients... So does this mean that I have to add some special data control mechanism (making socket descriptor a shared object?) q2 Hypothetical situtation Some user A attempts to send 15k of data to server. In one send he only sends 5k of data (partial send). The server handles it correctly (thus r3) and waits for the rest 10k to arrive. At this very moment some user B sends some other piece of data to the server... and guess what ? Our poor server thinks that this is the rest of data from user A and thus treats it respectively, which is absolutely not what we would like it to do... Is such situation possible? Do we then need to include not only data size but also some sort of user id to make sure that everything runs smoothly?

Share this post


Link to post
Share on other sites
From what it sounds like, you should just start working on it instead of thinking about every little detail... like your hypothetical situtation, if you would work on it you would find the answer pretty easy. For one you knows what sockets are being polled, and wont throw everything from all the sockets into one buffer, unless you're weird.

Also, select is used for the fall back engine (last resort) in ircu when nothing else is available, it's portable though.

Share this post


Link to post
Share on other sites
Each user's data will arrive on a separate socket in TCP, so no confusion is possible.

Using 1,000 threads is a very bad idea. Check the FAQ for more pointers and advice.

I would start out with select(), and switch to a more efficient platform-dependent model if and when that stops working well enough.

If select() returns a file descriptor for reading, then calling recv() on that socket will not block, and will return at least 1 byte of data (may not return all that you asked for, though).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by pnroach
Hi there!


Hi! :)

Quote:

q1 In some of the papers I've read, people suggest using one thread per user so that our socket is non-blocking. Is this a realistic approach, taking
into consideration r1? Do real world applications that deal with thousands of users use this approach?

Cease to read these papers if they don't specify that this is only fine if you're using a very few threads/sockets. This is not a particularly good way of doing things if you are talking over 1,000 connections. I speak from experience ;)

Quote:

I am considering using **select** function to achieve multiplexing. Can I just put **select** + some additional code in a separate thread
and have it checking users joining and leaving and also reading data from socket when there's data to read? At the same time I want to be able
to send data to clients... So does this mean that I have to add some special data control mechanism (making socket descriptor a shared object?)

This is a much nicer solution, mainly because it's exactly what I do. I use a separate thread which uses *select* to process a group of socket descriptors.

Quote:

q2 Hypothetical situtation

Some user A attempts to send 15k of data to server. In one send he only sends 5k of data (partial send). The server handles it correctly (thus r3) and
waits for the rest 10k to arrive. At this very moment some user B sends some other piece of data to the server... and guess what ? Our poor server
thinks that this is the rest of data from user A and thus treats it respectively, which is absolutely not what we would like it to do...

Is such situation possible? Do we then need to include not only data size but also some sort of user id to make sure that everything runs smoothly?


When you accept a connection you will palm it off to another socket, so you have a "client" socket per client. When client A sends his/her 5k clientsocket A will stick it in a buffer. Then client B sends some data which will end up in clientsocket B's pocket.

You don't need to worry about them getting mixed up.

Share this post


Link to post
Share on other sites
Quote:


When you accept a connection you will palm it off to another socket, so you have a "client" socket per client. When client A sends his/her 5k clientsocket A will stick it in a buffer. Then client B sends some data which will end up in clientsocket B's pocket.

You don't need to worry about them getting mixed up.


Thank you Mr Anonymous!


I realized this about 5 minutes ago while reading through yet another paper X)

Thanx a lot for practical considerations you've given

Share this post


Link to post
Share on other sites
i have an idea (sprung from the well), have users route to different ports, after they "check-in" on a common port.

common port 20050
user port 20051 -> 29999

,... there is too much overhead w/ a 1000 threads, use a thread for a particular context, vs. a particular user, like File_X would have its own thread or StarCraft_Lobby would have its own thread. Then just have an array of classes or something and cycle through all the ports / assigned users.

just a thought.

Share this post


Link to post
Share on other sites

This topic is 4195 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