我相信你的問題與你正在使用的代碼的異步性質。你擁有的是一個開放的連接,你在套接字上調用了異步的read
方法。 這會從通道中讀取n
字節,其中n
是0
之間的任何值,與可用緩衝區的大小相同。
我堅信你必須循環閱讀。也就是說,用Java的A-NIO;你需要通過再次從completed
方法調用read
您CompletionHandler
,可能在AsynchronousSocketChannel
通過作爲附件到一個新的completed
方法上CompletionHandler
您創建read
,而不是一個你已經有accept
方法。
我認爲這是同一種模式,你會使用,你會再次this
在CompletionHandler
你使用的accept
方法調用調用accept
爲完成處理從completed
方法。
它便成爲重要的是把一個「逃生」條款到您的CompletionHandler
例如,如果result
是-1
或者如果ByteBuffer
讀過X
根據你期待什麼,或者如果最終基於字節數byte
ByteBuffer
是您已經與發送應用程序達成一致的特定消息終止字節。
對此事的Java Documentation去,至於說read
方法只會在調用時讀取的字節對dst
量。
總結; completed
方法調用read
的處理程序似乎在一些事情被寫入通道後執行;但是如果有東西正在流傳,你可能會得到一半的字節,所以你需要繼續閱讀,直到你滿意爲止,你已經完成了他們發送的內容。
下面是一些代碼,我一直在閱讀,直到最後,在異步閱讀時作出響應。它不像我自己,可以同時談話和傾聽。
public class ReadForeverCompletionHandler implements CompletionHandler<Integer, Pair<AsynchronousSocketChannel, ByteBuffer>> {
@Override
public void completed(Integer bytesRead, Pair<AsynchronousSocketChannel, ByteBuffer> statefulStuff) {
if(bytesRead != -1) {
final ByteBuffer receivedByteBuffer = statefulStuff.getRight();
final AsynchronousSocketChannel theSocketChannel = statefulStuff.getLeft();
if (receivedByteBuffer.position()>8) {
//New buffer as existing buffer is in use
ByteBuffer response = ByteBuffer.wrap(receivedByteBuffer.array());
receivedByteBuffer.clear(); //safe as we've not got any outstanding or in progress reads, yet.
theSocketChannel.read(receivedByteBuffer,statefulStuff,this); //Basically "WAIT" on more data
Future<Integer> ignoredBytesWrittenResult = theSocketChannel.write(response);
}
}
else {
//connection was closed code
try {
statefulStuff.getLeft().shutdownOutput(); //maybe
}
catch (IOException somethingBad){
//fire
}
}
}
@Override
public void failed(Throwable exc, Pair<AsynchronousSocketChannel, ByteBuffer> attachment) {
//shout fire
}
的讀取時最初從completed
方法拉開序幕由呼叫處理程序從最原始的異步accept
服務器套接字像
public class AcceptForeverCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Pair<AsynchronousServerSocketChannel, Collection<AsynchronousSocketChannel>>> {
private final ReadForeverCompletionHandler readForeverAndEverAndSoOn = new ReadForeverCompletionHandler();
@Override
public void completed(AsynchronousSocketChannel result, Pair<AsynchronousServerSocketChannel, Collection<AsynchronousSocketChannel>> statefulStuff) {
statefulStuff.getLeft().accept(statefulStuff, this); //Accept more new connections please as we go
statefulStuff.getRight().add(result); //Collect these in case we want to for some reason, I don't know
ByteBuffer buffer = ByteBuffer.allocate(4098); //4k seems a nice number
result.read(buffer, Pair.of(result, buffer),readForeverAndEverAndSoOn); //Kick off the read "forever"
}
@Override
public void failed(Throwable exc, Pair<AsynchronousServerSocketChannel, Collection<AsynchronousSocketChannel>> attachment) {
//Shout fire
}
}
沒有這樣的事作爲TCP中的消息。這是一個字節流協議。如果你想要消息,你必須自己實現它們。 – EJP
對不起,我正在使用一個瀏覽器,我相信這個瀏覽器是通過一個'byte []'發送的,對我而言這個詞的選擇不正確 – Hooli
同樣的區別。 'Message'=='byte array'在這種情況下。這是一個字節流協議。沒有什麼說可以在單個操作中接收整個發送的字節數組。 – EJP