Jump to content
  • Advertisement
Sign in to follow this  
invictus

Non-blocking sockets limitations?

This topic is 3534 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 is a question I have been wondering about non-blocking sockets. With blocking sockets I can just ask the program to wait for input data, but with non-blocking sockets I obviously need to ask for data at the correct times...what happens if I dont? Lets assume some data arrives on the socket, but due to some other heavy processing on the thread, it takes a few seconds before the app checks for incoming data...is the data lost/dropped in the meantime? How much time/data do I have between the data actually arrives until I have to be read in order for me to actually being able to read it? I really appreciate any feedback you might have!

Share this post


Link to post
Share on other sites
Advertisement
This will depend on what protocol and platform you are using, but generally, with blocking or non-blocking sockets, when data comes over the network interface, the data gets written to a buffer by the OS. With non-blocking sockets, when you call recv(), the function checks for anything in the buffer, and if there's stuff there, returns it. If you go too long without calling recv() the buffer overflows and then you start losing data. How big that buffer is and how quickly that fills will depends on the OS and your application's data throughput. You can find the size of the buffer for a given socket with a call to getsockopt() with an SO_RCVBUF argument and you can determine how much data is in the buffer with a call to ioctlsocket() with an FIONREAD argument.

Share this post


Link to post
Share on other sites
Each socket has internal send and receive buffers. 8kb by default, 64kb max.

If UDP socket receives a packet when that buffer is full, packet is silently discarded.

With TCP, there's an internal window which determines how much data can be sent, so overflow shouldn't occur. This window may be of different size than socket's buffers.

Quote:
How much time/data do I have between the data actually arrives until I have to be read in order for me to actually being able to read it


Worst-case UDP: 64kb / Bandwidth_in_kb (for 100Mbit that's about once every 6ms).
TCP: shouldn't matter, but once every few seconds

However, since network reads are typically cheap, you might as well run a higher-priority thread for networking.

Share this post


Link to post
Share on other sites
You can set the buffers bigger than 64K on some platforms. Beware though - the relevant setsockopt call to set the buffer size can return with a success value but not actually increase it to the size you requested. Use getsockopt to see what it gave you.

Share this post


Link to post
Share on other sites
Quote:
Original post by SteveTaylor
I would recommend always using a separate input thread, but only one for the lifetime of the program, not one per connection.


For example?

Share this post


Link to post
Share on other sites
Quote:
Original post by SteveTaylor
I would recommend always using a separate input thread, but only one for the lifetime of the program, not one per connection.


So lets assume I have a UDP application

I process data and send udp-packets during processing. Instead of also receiving data in between processing its recommended to have a separate thread reading (maybe even blocking) on the thread and dumping it in an application level buffer until the main(processing) thread have time to pick it up? In that case it will always read the data as it arrives, and nothing needs to be dropped although I utilize the main thread for processing?

Is this a better idea?

Share this post


Link to post
Share on other sites
You really shouldn't be doing network input (or any kind of input) from
your main thread "that could get busy". Run your input in a separate thread
with suitable priority. Let it preprocess and bless input, so your main
thread will never see anything except complete, valid data.

Share this post


Link to post
Share on other sites
As long as socket buffers are large enough, you will not drop any data, no matter how fast or slow you are reading.
Reading on a high-priority thread (that can block on the socket, if you're using UDP) is useful if you want accurate time-stamps for incoming packets.
If you don't need that, and if your buffers are large enough, you can just as well receive in the main thread; the CPU cycle difference is minimal.
Note that, if you receive packets faster than you can process them, the application buffer/queue will grow to unbounded size. You'll need some way of dealing with this case.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!