Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java NIO Threading issue with SocketChannel.write()

Tags:

java

sockets

nio

Sometimes, while sending a large amount of data via SocketChannel.write(), the underlying TCP buffer gets filled up, and I have to continually re-try the write() until the data is all sent.

So, I might have something like this:

public void send(ByteBuffer bb, SocketChannel sc){
   sc.write(bb);
   while (bb.remaining()>0){
      Thread.sleep(10);
      sc.write(bb);          
   }
}

The problem is that the occasional issue with a large ByteBuffer and an overflowing underlying TCP buffer means that this call to send() will block for an unexpected amount of time. In my project, there are hundreds of clients connected simultaneously, and one delay caused by one socket connection can bring the whole system to a crawl until this one delay with one SocketChannel is resolved. When a delay occurs, it can cause a chain reaction of slowing down in other areas of the project, and having low latency is important.

I need a solution that will take care of this TCP buffer overflow issue transparently and without causing everything to block when multiple calls to SocketChannel.write() are needed. I have considered putting send() into a separate class extending Thread so it runs as its own thread and does not block the calling code. However, I am concerned about the overhead necessary in creating a thread for EACH socket connection I am maintaining, especially when 99% of the time, SocketChannel.write() succeeds on the first try, meaning there's no need for the thread to be there. (In other words, putting send() in a separate thread is really only needed if the while() loop is used -- only in cases where there is a buffer issue, perhaps 1% of the time) If there is a buffer issue only 1% of the time, I don't need the overhead of a thread for the other 99% of calls to send().

I hope that makes sense... I could really use some suggestions. Thanks!

like image 344
DivideByHero Avatar asked Dec 07 '25 18:12

DivideByHero


1 Answers

You don't need the sleep() as the write will either return immediately or block. You could have an executor which you pass the write to if it doesn't write the first time. Another option is to have a small pool of thread to perform the writes.

However, the best option for you may be to use a Selector (as has been suggested) so you know when a socket is ready to perform another write.

like image 57
Peter Lawrey Avatar answered Dec 10 '25 08:12

Peter Lawrey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!