Because of my infancy in network programming (I've been learning/using winsock 1.1 for about a month now) I've come here asking for some guidance, as I'm not familiar with the potential of particular implimentation methods to meet my expectations.
I am currently beginning implimentation of a TCP server using windows sockets, which I would like to keep compatible with Berkeley sockets for future porting to linux.
To this end, I'm currently using non-blocking sockets.
The design right now only runs in a single thread, using select(). I've read that a select-based server is more scalable than one using a single thread to handle each user connected (edit: meaning multiple threads to handle all users), via a blocking socket. If I'm wrong on this, please explain. (My main source thus far has been the Winsock Programmers' FAQ.)
I would like this server to be scalable to support at least a few hundred clients at some point in the future. Yes, this is for an online game of sorts.
![](smile.gif)
My current notion is that while the server is processing the game universe, it will come upon things which it must inform certain/all users about.
I had envisioned using a separate buffer or queue stored for each user which would hold information which could not immediately be sent when the server decides a user needs to be notified. I see a possibility of sending messages out of order with this EXACT method, however... I'd imagine there to be better "grouping" strategies than this, of course. Please feel free to enlighten me.
Having read a bit on asynchronous sockets, I know that if a call to send or recv would block on a particular asynchronous socket, the WSAEWOULDBLOCK error would be returned. Would something like this be the case for non-blocking sockets as well? I wouldn't think that Berkeley sockets would use an error named according to the Winsock API, but perhaps there's a comparable error that would be indicated?
Assuming that there would be some indication that a call would block, I thought of it working something like this:
(In game logic portion of server code)
// Try sending user some necessary message
// If send would block, place message in queue
(In the select() portion of code)
// Try sending users the messages on the queue, in order
If there would not be some indication of a call that would block, I figure that either:
1) Trying to send a message outside the select()'s jursidiction would be unsafe
or
2) Trying to send a message on a non-blocking socket will always indicate success as long as the message will eventually be sent
If it's neither, I need some info badly
![](smile.gif)
Now, obviously (or not so obviously?), the server wouldn't normally come to points in the logic where it determines that it needs to read from the user... instead, the client implimentation would have (comparable?) code which tries it's own attempts to send to the server within its game logic.
Therefore, I only forsee recv being called within the logic where select() is called, filling up a reading buffer on that particular user for the server's use.
What I'm looking for then, other than answers to my indirect questions (I just sort of stated what I thought might work) is general guidance, comments, corrections, anything at all regarding anything I've stated here.
If I'm way out in left field without a glove, please tell me so. If I should scrap everything I've thought about the way it all works, and should do something else entirely, let me know.
Thanks in advance to all who offer their assistance.
Edited by - Redleaf on May 20, 2001 6:06:05 PM