Надежная запись в Java SocketChannel

У меня возник вопрос относительно java SocketChannel.

Скажем, у меня есть канал сокета, открытый в режиме блокировки; после вызова метода write(ByteBuffer) я получаю целое число, описывающее, сколько байтов было записано. В javadoc указано: "Возврат: количество записанных байтов, возможно, ноль"

Но что точно это означает? означает ли это, что количество байтов действительно было доставлено клиенту (так что отправитель получил tcp ack, из которого видно, сколько байтов было получено сервером), или это означает, что количество байтов было записано в стек tcp? (чтобы некоторые байты все еще могли ожидать, например, в буфере сетевой карты).


person johny_walker    schedule 13.09.2010    source источник


Ответы (2)


означает ли это, что количество байтов действительно было доставлено клиенту

Нет. Это просто означает количество байтов, доставленных в локальный сетевой стек.

Единственный способ убедиться, что данные были доставлены в удаленное приложение, — это получить подтверждение на уровне приложения для данных.

person Stephen C    schedule 13.09.2010
comment
Спасибо за ответ. Я думаю, мне следует изучить, как сокеты berkley реализованы в различных ОС, чтобы понять это точно - person johny_walker; 13.09.2010
comment
@Stephen C Обеспечивает ли SocketChannel надежность того, что все записанные байты обязательно будут доставлены на удаленный SocketChannel? - person rns; 09.08.2014
comment
@Soni - Нет, не так. В случае сбоя сети отправленные байты могут никогда не быть получены. Действительно, существует небольшая вероятность того, что данные могут быть повреждены при передаче, а повреждение не будет обнаружено. - person Stephen C; 09.08.2014
comment
Не могли бы вы предоставить источники для вашего ответа, пожалуйста? - person mike; 10.02.2015
comment
@Майк - у меня его нет. Это общеизвестно. Этому я научился более 30 лет назад, когда впервые узнал о TCP/IP, сокетах и ​​так далее. Однако, если ››вы‹‹ найдете достойные источники, дайте мне знать, и я добавлю их к ответу. - person Stephen C; 11.02.2015

Параграф, который вас смущает, относится к неблокирующему вводу-выводу.

Для неблокирующей операции ваш первоначальный вызов действительно может ничего не записывать во время вызова.

Если не указано иное, операция записи завершится только после записи всех r запрошенных байтов. Некоторые типы каналов, в зависимости от их состояния, могут записывать только некоторые байты или, возможно, вообще ничего не записывать. Канал сокета в неблокирующем режиме, например, не может записать больше байтов, чем свободно в выходном буфере сокета.

Как вы можете видеть, для блокировки ввода-вывода будут отправлены все байты (или возникнет исключение в середине отправки)

Обратите внимание, что нет никакой гарантии, когда байты появятся на принимающей стороне, это полностью зависит от протокола сокетов низкого уровня.

person Alexander Pogrebnyak    schedule 13.09.2010
comment
Я понимаю проблему блокировки/неблокировки, мой вопрос скорее заключался в том, могу ли я (после записи байтов) полагаться на тот факт, что запрошенные байты были доставлены на удаленную сторону или просто в локальный стек tcp/ip. В любом случае спасибо за комментарий - person johny_walker; 13.09.2010