我一直在使用AsychronousSockets,但遇到運行大負載時接收ReadPendingException的問題。使用AsynchronousSocketChannel時的ReadPendingException
一些上下文: 我想客戶端異步發送消息到服務器,然後監聽響應。
響應可以是3種類型中的一種,而AsynchronousSocketChannel的讀取需要預定大小的ByteBuffer。因此,我的解決方案是有兩個讀取:第一個接收消息的類型(以4字節傳遞,一個int),然後是另一個讀取,它將構造適當大小的字節緩衝區來處理其餘的的消息。
我認爲這裏的主要問題伴隨着這樣一個事實,即當調用CompletetionHandler的完整方法時,並不一定意味着ByteBuffer的讀取完成。爲了解決這個問題,我創建了一個while循環,直到ByteBuffer已滿爲止。
然而,在while循環中讀取的內容似乎偶爾會與其他讀取相沖突,即當我收到ReadPendingException時。
基本骨架代碼:
AsynchronousChannelGroup mThreadGroup= AsynchronousChannelGroup.withFixedThreadPool(100, Executors.defaultThreadFactory());
AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(mThreadGroup);
InetSocketAddress hostAddress = new InetSocketAddress("localhost", 12345);
// Connect to server
channel.connect(hostAddress, null, new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
// Write some message to server
ByteBuffer message = ...
channel.write(message, null, new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
// Now that we have sent the message, listen for a response type
ByteBuffer responseType = ...
channel.read(responseType, null, new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
// parse response type, do some other stuff...
// ...
// After other stuff, create new byte buffer for main message
ByteBuffer receiveMessage = ...
channel.read(receiveMessage, null, new CompletionHandler<Void, Void>() {
@Override
public void completed(Void result, Void attachment) {
// The read may not have been completed, so make sure that it is
while (receiveMessage.remaining() > 0) {
channel.read(receiveMessage);
}
// Handle receiveMessage...
}
@Override
public void failed(Throwable exc, Void attachment) {}
});
}
@Override
public void failed(Throwable exc, Void attachment) {}
});
}
public void failed(Throwable exc, Void attachment) {}
});
}
@Override
public void failed(Throwable exc, Void attachment) {}
});
所以我的問題是這樣雙重的:
有沒有獲得代碼的方式,如上圖所示,正常工作(又名不再接收ReadPendingException)?
是否有更好的方法來設置相同的功能?
非常感謝你們提供任何可能的幫助。