Java SocketChannel: почему wrap-flip-write не работает, а wrap-write работает?

Предположим, у нас есть Java SocketChannel подключен к серверу, который ожидает поступления данных:

SocketChannel server = SocketChannel.open();
server.connect(new InetSocketAddress(ip, port));

И мы отправляем наш запрос, как показано ниже:

byte[] request = "This is a request for server!".getBytes();
ByteBuffer buffer = ByteBuffer.wrap(request);
buffer.flip();
int write = 0;
while (buffer.hasRemaining())
    write += server.write(buffer);
System.out.println(write);

Код выше возвращает 0 что означает, что он не записывает байты на канал!

Но если я уберу buffer.flip() линия, она будет работать нормально и данные отправляются:

byte[] request = "This is a request for server!".getBytes();
ByteBuffer buffer = ByteBuffer.wrap(request);
int write = 0;
while (buffer.hasRemaining())
    write += server.write(buffer);
System.out.println(write);

Почему это?!

2 ответа

Решение

Я выяснил проблему сам, поэтому я пишу это здесь Stackru поделиться информацией и быть полезным для всех, кто сталкивается с той же проблемой.

Согласно документу Java для ByteBuffer.wrap():

Емкость и предел нового буфера будут array.length, его позиция будет равна нулю, а отметка будет неопределенной.

И Java-документ для Buffer.flip() говорит:

Переворачивает этот буфер. Предел устанавливается на текущую позицию, а затем позиция устанавливается на ноль. Если метка определена, то она отбрасывается.

Ответ теперь ясен: wrap() устанавливает позицию буфера в ноль, и flip() устанавливает ограничение буфера на текущую позицию (которая равна нулю), и write(buffer) начнется с позиции до предела, которые оба 0при этом ничего не пишет!

wrap() доставляет буфер, который уже перевернут. Повторное перелистывание в основном очищает его с точки зрения write() или get().

Другие вопросы по тегам