What is the point of blocking sockets?

Started by
4 comments, last by Nypyren 10 years ago

I have never understood the point of blocking sockets. Even in a multithreading setting the socket would block indefinitely and force you to terminate the thread.

Apart from toy programs - is there a use for blocking sockets?

Advertisement
Yeah in practice you'd want almost all of your async APIs to be non-blocking ;-)

If your program really has no work to do except to wait for a network response, then blocking sockets may make the code a lot simpler.
Recently I had a tool like this - it received a description of a texture file operation (like changing the pixel storage format), then received the pixels, then sent the results back. The program on the other end (sending source textures and receiving results) was completely serial, Ono processing one texture at a time. There was no advantage in using async communication in that case ;)

Blocking sockets wake when they have data available, if you use blocking sockets you will usually have that on its own thread. The benefit you get is immediate response to incoming data. The alternative is to check the socket every n seconds (where n is the delta of your polling, if you poll at 60fps for example then n will be 16.66r-ms. This may seem a negligent amount of time, and for many application it is.

However, if we take into account a simple PING operation, the PING response could have an added latency of up-to 16ms in the worst case (in the given example).

It is entirely up-to the developer if the added latency is acceptable or not and choose which direction they wish to take, but blocking sockets can lead to (relatively) much more responsive network processing. Whether that's a requirement or not is down to what you're doing and how you implement it though, really.

n!


Apart from toy programs - is there a use for blocking sockets?

Using a blocking socket is a common and sane way to implement a server. In fact, it's pretty rare that you need non-blocking sockets in my experience.

Almost all servers I've had the pleasure of working with use socket multiplexing and blocking sockets. The code is simpler and less error-prone. Unless you've written erroneous code, it's not possible to block indefinitely on a read, because you only read when the multiplexor (select()/poll()/epoll()/kqueue() etc) indicates data is available.

Stephen M. Webb
Professional Free Software Developer

if you use blocking sockets you will usually have that on its own thread


Only for toy servers. In real servers, you rely on notifications that there is something to receive on a socket, and you call recv() once per receipt. recv() is guaranteed to return if it can return at least one byte, but it may return less than you ask for -- this is different from read() specifically to support this behavior.

The old-school way of checking all your sockets for whether they will block or not when you call recv() (or send()) is to use select(). That still works fine, and can be used from your main thread.
The modern way of being told your sockets are ready is to use I/O completion ports (on Windows) or libevent (on UNIX.) A good platform-neutral wrapper is boost::asio.
enum Bool { True, False, FileNotFound };
Many (non-game) programs - typically command-line tools - don't need to do anything else while they're waiting for data. In those cases, it's easiest to use blocking calls since the code is much simpler.

This topic is closed to new replies.

Advertisement