這不是我第一次試圖瞭解這個問題,但我希望這將是最後一個:的Java NIO的read()返回-1
一些背景:
我有一個Java SocketChannel NIO
服務器工作在非阻塞模式下。
此服務器有多個客戶端,它們發送和接收來自它的消息。
每個客戶端每隔一段時間就會保持其與服務器的連接,並提供"keepalive"
消息。 服務器的主要思想是客戶端將始終保持「連接」狀態,並以「推送」模式從它接收消息。
現在我的問題:
用Java NIOread()
功能
- 當讀()返回-1 - 這意味着它的EOS。
在我問 here我意識到,這意味着該插座完成當前流,並不需要被關閉的問題..
在谷歌搜索更多的關於這一點,我發現當它確實意味着連接在另一端被關閉。
「流」這個詞究竟意味着什麼?它是從客戶端發送的當前消息嗎?客戶端連接能否發送消息?
爲什麼客戶端的
SocketChannel
會關閉?如果客戶端從未告訴他關閉?read()
return -1和通過對等I/O錯誤重置連接有什麼區別?
這是我從SocketChannel
閱讀:
private JSONObject readIncomingData(SocketChannel socketChannel)
throws JSONException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
JSONObject returnObject = null;
ByteBuffer buffer = ByteBuffer.allocate(1024);
Charset charset = Charset.forName("UTF-8");
String endOfMesesage = "\"}";
String message = "";
StringBuilder input = new StringBuilder();
boolean continueReading = true;
while (continueReading && socketChannel.isOpen())
{
buffer.clear();
int bytesRead = socketChannel.read(buffer);
if (bytesRead == -1)
{
continueReading = false;
continue;
}
buffer.flip();
input.append(charset.decode(buffer));
message = input.toString();
if (message.contains(endOfMesesage))
continueReading = false;
}
if (input.length() > 0 && message.contains(endOfMesesage))
{
JSONObject messageJson = new JSONObject(input.toString());
returnObject = new JSONObject(encrypter.decrypt(messageJson.getString("m")));
}
return returnObject;
}
確定,但將拉出網絡電纜返回-1或通過對等錯誤發送連接重置? 你有重新編碼的建議嗎? 爲了避免丟失消息,客戶端一次僅發送一條消息 –
拉出電纜將在超時後導致異常。我建議重新編碼,以便保留所有讀取的數據,而不僅僅是您期望的數據。 read()會給你1個字節和緩衝區的最大大小。一次只發送一條消息並不意味着只會一次收到一條消息,並不能保證第一次讀取()將是一個完整的消息。 –