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().