Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-blocking socket writes in Java versus blocking socket writes

Why would someone prefer blocking writes over non-blocking writes? My understanding is that you would only want blocking write if you want to make sure the other side got the TCP packet once the write method returned, but I am not even sure that's possible. You would have to flush and flush would have to flush the underlying operating system write socket buffer. So is there any disadvantage of non-blocking socket writes? Does having a large underlying write socket buffer a bad idea in terms of performance? My understanding is that the smaller the underlying socket write buffer the more likely you will hit slow/buggy client and have to drop/queue packets in the application level while the underlying socket buffer is full and isWritable() is returning false.

like image 752
chrisapotek Avatar asked Nov 10 '11 21:11

chrisapotek


People also ask

What is the difference between blocking and non-blocking sockets?

If the blocking mode is set for a socket, the calling program is suspended until the expected event completes. If nonblocking is set by the FCNTL() or IOCTL() calls, the calling program continues even though the I/O call might not have completed.

What is blocking and non-blocking in socket programming?

A socket can be in "blocking mode" or "nonblocking mode." The functions of sockets in blocking (or synchronous) mode do not return until they can complete their action. This is called blocking because the socket whose function was called cannot do anything — is blocked — until the call returns.

Is Java blocking or nonblocking?

Java NIO is an asynchronous IO or non-blocking IO. For instance, a thread needs some data from the buffer. While the channel reads data into the buffer, the thread can do something else. Once data is read into the buffer, the thread can then continue processing it.

Is socket send blocking?

In case of blocking socket: The send() will block if the kernel buffer is not free enough to intake the data provided to send() call. Non blocking sockets: send() will not block, but would fail and returns -1 or it may return number of bytes copied partially(depending on the buffer space available).


2 Answers

My understanding is that you would only want blocking write if you want to make sure the other side got the TCP packet once the write method returned

Your understanding is incorrect. It doesn't ensure that.

Blocking writes block until all the data has been transferred to the socket send buffer, from where it is transferred asynchronously to the network. If the reader is slow, his socket receive buffer will fill up, which will eventually cause your socket send buffer to fill up, which will cause a blocking write to block, blocking the whole thread. Non-blocking I/O gives you a way to detect and handle that situation.

like image 100
user207421 Avatar answered Sep 28 '22 14:09

user207421


The problem with non blocking writes is that you may not have anything useful to do if the write is incomplete. You can end up with loops like

// non-blocking write
while(bb.remaining() > 0) sc.write(bb);

OR

// blocking write
sc.write(bb);

The first can burn CPU and the second might be more desirable.

The big problem is reads. Once you decide whether you want blocking or non-blocking reads, your writes have to be the same. Unfortunately there is no way to make them different. If you want non-blocking reads, you have to have non-blocking writes.

like image 45
Peter Lawrey Avatar answered Sep 28 '22 15:09

Peter Lawrey