2011-02-28 2 views
2

Когда я использую класс Socket Javaa для отправки массива байтов, выполняет ли вызов записи в следующем блоке кода до тех пор, пока он не подтвердит, что получатель получил данные?Является ли класс класса Socket Socket Java при отправке данных

byte data[] = ...; 
Socket socket = ...; 

socket.getOutputStream().write(data); // blocking ? 

Причина, почему я спрашиваю, если у меня есть список сокетов, которые я хочу отправить те же данные, я хочу, чтобы отправить его как можно более эффективно, то есть, есть ли лучший способ, чем это:

ArrayList<Socket> sockets = ...; 
byte data[] = ...; 

for(int i = 0; i < sockets.size(); i++) 
    sockets.getOutputStream().write(data); 

ответ

5

TCP-рукопожатие происходит в connect(2) время, не write(2) времени.

Звонки на write(2) будут блокироваться до тех пор, пока буфер отправки TCP-протокола не будет исчерпан, чтобы принимать больше данных из программы. (Я не могу представить, чтобы ОС разблокировала операцию write(2) для одного свободного байта.)

Единственная гарантия, что у вас есть то, что клиент принял данные в прошлом и не отстает от размера TCP окно для сеанса плюс размер внутренних буферов ОС. Независимо от того, достигло ли какое-либо из этих данных приложение на другой конечной точке, это еще один уровень буферов - стек TCP на удаленном одноранговом узле подтвердит полученные данные и сохранит их в буферах, прежде чем приложение получит возможность обрабатывать Это.

+0

Итак, вы говорите, что он будет разблокирован, как только данные достигнут уровня tcp в стеке, не дожидаясь завершения полного рукопожатия tcp с клиентом? –

+0

@gamemb, ваш код не перейдет к вызовам 'write()' до тех пор, пока не будет завершено рукопожатие. (Рукопожатие происходит один раз за сеанс на 'connect()' время.) Но в остальном, да, код будет разблокирован, когда буферы _local_ TCP send освободят достаточно места для принятия вызовов 'write()', которые могут быть 64 КБ window + размер буфера 8 Кбайт впереди того, что получил удаленный одноранговый узел, и 'ACK'ed. – sarnold

+0

(Обратите внимание, что окно с 64 КБ - это всего лишь догадка - с [масштабированием окна TCP] (http://en.wikipedia.org/wiki/TCP_window_scale_option), окно может быть мегабайтами большими, почти до гигабайта данных. для передачи данных в один гигабайт потребуется специализированные среды. – sarnold