Иногда при отправке большого количества данных через SocketChannel.write() базовый буфер TCP заполняется, и мне приходится постоянно повторять попытку записи(), пока все данные не будут отправлены.
Итак, у меня может быть что-то вроде этого:
public void send(ByteBuffer bb, SocketChannel sc){
sc.write(bb);
while (bb.remaining()>0){
Thread.sleep(10);
sc.write(bb);
}
}
Проблема в том, что случайная проблема с большим ByteBuffer и переполнением базового буфера TCP означает, что этот вызов send() будет заблокирован на неожиданное время. В моем проекте одновременно подключены сотни клиентов, и одна задержка, вызванная подключением к одному сокету, может вывести всю систему из строя, пока не будет устранена эта одна задержка с одним SocketChannel. Когда возникает задержка, это может вызвать цепную реакцию замедления в других областях проекта, и важно иметь низкую задержку.
Мне нужно решение, которое позаботится об этой проблеме переполнения буфера TCP прозрачно и не приведет к блокировке всего, когда необходимы несколько вызовов SocketChannel.write(). Я подумал о том, чтобы поместить send() в отдельный класс, расширяющий Thread, чтобы он работал как отдельный поток и не блокировал вызывающий код. Тем не менее, я обеспокоен накладными расходами, необходимыми для создания потока для КАЖДОГО подключения к сокету, которое я поддерживаю, особенно когда в 99% случаев SocketChannel.write() завершается успешно с первой попытки, а это означает, что нет необходимости в потоке. . (Другими словами, размещение send() в отдельном потоке действительно необходимо только в том случае, если используется цикл while() - только в случаях, когда есть проблема с буфером, возможно, в 1% случаев) Если есть проблема с буфером только 1% времени, мне не нужны накладные расходы на поток для остальных 99% вызовов send().
Я надеюсь, что это имеет смысл... Я мог бы действительно использовать некоторые предложения. Спасибо!