2016-06-20 3 views
1

Я использую java 7's nio2 AsynchronousSocketChannel для выполнения операций чтения и записи с использованием CompletionHandlers. Во-первых, я хотел бы знать, гарантирована ли операция записи, полностью или нет, ByteBuffer. Если это частичная запись, использование CompletionHandler's - это способ полностью выписать ByteBuffer. Может быть, использование рекурсии?NIO2 AsynchronousSocketChannel чтение/запись полностью с использованием CompletionHandler

То же самое касается чтения. Я гарантированно полностью прочитаю все сообщение из AsynchronousSocketchannel или может быть частично прочитанным. Если это так, снова используя CompletionHandlers, как я могу написать обработчик, который будет выполнять полную операцию чтения.

Благодарим Вас заранее Фрэнсис

+1

Там нет такого понятия, как сообщение в TCP , Это поток байтов. Поэтому ответить на оба вопроса нет. – EJP

ответ

1

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

Для полного чтения/записи надежно вам нужно повторить операцию read/write до тех пор, пока существует некоторое оставшееся пространство/байт в буфере:

ByteBuffer buffer = ByteBuffer.allocate(full_size_I_do_expect); 
channel.read(buffer, null, 
    new CompletionHandler() { 
     @Override 
     public void completed(Integer result, Object attachment) { 
      if (result < 0) { 
       // handle unexpected connection close 
      } 
      else if (buffer.remaining() > 0) { 
       // repeat the call with the same CompletionHandler 
       channel.read(buffer, null, this); 
      } 
      else { 
       // got all data, process the buffer 
      } 
     } 
     @Override 
     public void failed(Throwable e, Object attachment) { 
      // handle the failure 
     } 
}); 
+0

result = 0 не означает, что соединение закрыто, 0 байтов можно читать нормально, -1 означает соединение закрывается – Artyom

+0

@ArtyomNikolaev: ну, на самом деле, это не так, как правило, это может произойти только в том случае, если размещен запрос на чтение 0 байтов. Это будет означать, как правило, ошибку в программе (возможно, в результате получается бесконечный цикл, поэтому в любом случае может быть безопаснее убить соединение :-)). Но вы правы, комментарий о закрытом соединении не был точным, я обновил код. –

+0

Не является ли результат '0 == 0' просто показателем, что вы читаете быстрее, чем вы получили? Я все еще работаю над некоторым из этого кода NIN для Async; но, казалось бы, если читать еще нечего, он просто выполняет обработчик завершения с нулевыми байтами. Делает ли это тогда цикл, пока вы не получите больше байтов или пока не получите EOS? В документе Java предлагается следующее: «Где r равно 0, операция чтения немедленно завершается с результатом 0 без инициирования операции ввода-вывода» [JavaDoc] (https://docs.oracle.com/javase/7/docs/ API/Java/NiO/каналы/AsynchronousSocketChannel.html) – iZian

Смежные вопросы