Advertisement

Clearup about threads and winsock ..

Started by May 18, 2002 07:34 AM
6 comments, last by Tylon 22 years, 8 months ago
When you send something on a tcp stream connection does that mean that the process will wait untill the data is streamed, or is the information sortof ''posted'' to the winsock dll so that there is no considerable wait time regardless of the size of the packet? Also, when I found out there is incoming data on a socket (either by select, or message from asynch socket) does recv''ing from it take time and make the process wait untill it got all the data while its still streaming, or does it just instantly recv the data it got so far and return with out blocking the process? If recv and send functions do ''take time in some cases'' like I mentioned above, then I assume I have to make my server multithreaded, ie create new threads for sends and recv''s if i want to keep my server functioning at all time .. ? ie if it is a game server, then every frame on the game engine has to be constant, so a frame cant be prolonged occasionally due to more sends or recv''s. I hope you understood my questions .
The process will wait until it can read from/write to the socket''s read/write buffer. The buffers are what communicate with the network.

send() will block if the send buffer is full, until the socket at the other end reads enough data. recv() will block if the receive buffer is empty, until the socket at the other end sends some data.

If you have found out that there is data to be read, that''s becase the data is already there. recv() will return at most that amount of data (and tell you how much, RTFM).

No, you do not want to keep creating new sockets to communicate with the same client. You don''t know _why_ they are not answering. It could be (and often is) a network problem rather than a client problem... or they could have crashed, or dropped the game, or already answered and _you_ lost the answer (ok, with TCP, the network stack manages lost/duplicate packets). Wait until they do their part of the work, add fault tolerance (read up on UDP networking, ahhh the joy of dropped packets). Clients missing server updates is part of the fun of writing a networked game. Do a lookup on ''stateful clients'', ''dead reckoning'' and other related topics.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Advertisement
Don''t forget you can also alter sockets to be non-blocking (ie send/recv return immediately) but I''m not entirely sure how this interacts with TCP (I assume it is much like a poll but using select is probably a better option there).

Things like web servers do often use multiple threads (one per client) which block on their sockets, but I doubt this is a good option for a realtime game.
I have experience with UDP communication, I asked this because I want to understand stream a bit more.

I think you might have misunderstood some of my questions thanks to my poor explenation

I understand blocking and non blocking, what I am talking about is the time the send and recv functions take once data can be sent/recieved.

I dont think i meantioned creating new sockets to communicate. I mean''t create new _threads_ for communication if the actual send recv functions take time.

I am familiar with dead reconing etc, but the scope of my questions dont really enter that area.

Thanks the help though.
quote:
Original post by Tylon
I dont think i meantioned creating new sockets to communicate. I mean''t create new _threads_ for communication if the actual send recv functions take time.



You don''t want that either. Use select() to poll which sockets are ready to read, read the data in a buffer of your own. Since you''re doing TCP, you do not have packet boundaries and will have to detect when a "message" is complete by yourself (i.e. save the data until you have a full message). Let the network thread block on select, that''s what it has been created for.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
ah yes, but right now, i dont have a seperate network thread, i do a non-blocking select (timeval of 0, 0)in the main loop. i take it this is a bad idea then yeah?

should I have a seperate network thread that blocks on select which is independant of the main game loop? And then maybe have it post messages to the main game''s window when a complete packet is recieved ...
Advertisement
The two architectures are possible. Either continuous polling with select() timing-out or blocking on select() in a different thread.

Polling may be a bit easier to handle (since it doesn''t involve threading), but you have to be sure that your per-update processing is fast enough that you don''t add latency into the I/O (what works fine for text MUDs may not work for I/O heavy games)

Having a non-blocking select() in a separate thread may (have to check) be a bad idea, as you might end up sticking your thread in a thight loop (capital-B-Bad). Logically, since it is an I/O system call, the OS should preempt the thread so you''re ok, but well, you never know until you try.

Having the network thread post completed messages into a queue for the main loop to process is a good idea. Especially if the main loop has little/nothing to do beside react to the commands from the network. Alternatively, you can have yet another thread handling AI & IO independent stuff, and communicating with the main thread via the same queue mechanism (or another queue, most probably, so that IO gets priority).

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Right, Im getting the hang of this now, Thanks

This topic is closed to new replies.

Advertisement