这不是我第一次尝试理解这个问题,但我希望这将是最后一次:
一些背景:
我有一个以非阻塞模式工作的 Java SocketChannel NIO
服务器。
该服务器有多个客户端,可以从中发送和接收消息。
每个客户端每隔一段时间就会通过“keepalive”
消息来维护与服务器的连接。
服务器的主要思想是客户端将“始终”保持连接并以“推送”模式接收来自服务器的消息。
现在回答我的问题:
在 Java NIO read()
函数中 - 当 read() 返回 -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;
}
最佳答案
“流”一词的确切含义是什么?这是从客户端发送的当前消息吗?客户端连接是否有能力发送更多消息?
流是指在两个位置之间流动的数据,通常是在客户端和服务器之间流动,但实际上它是任何类型的数据流动。例如。如果您从硬盘读取文件,您将使用 FileInputStream,它表示从光盘上的文件流向程序的数据。这是一个非常通用的概念。把它想象成一条河流,水就是数据。另外,它是一种非常酷的河流,可以让您控制水/数据的流动方式。
如果客户端从未告诉他关闭 SocketChannel,为什么客户端会关闭 SocketChannel?
如果客户端和服务器之间的连接重置或中断,则可能会发生这种情况。你的程序永远不应该假设连接只是存在并且永远不会中断。连接会因各种原因而中断,可能是网络组件不稳定,有人拔掉了最好留在原处的插头,或者无线网络出现故障。服务器也可能会关闭连接,例如如果服务器程序出现故障、出现错误或连接超时。永远记住,打开的连接是有限的资源,因此如果服务器闲置时间过长,服务器可能会决定关闭它们。
read() 返回 -1 和对等 I/O 错误导致连接重置之间有什么区别?
当 read() 返回 -1 时,这仅意味着流中当前没有更多数据。连接重置意味着可能还有更多数据,但连接不再存在,因此无法再读取该数据。再次采用河流类比:将数据视为使用连接两个村庄(连接)的河床从上游村庄(又名 Serverville)发送到下游村庄(又名 Clientville)的一定量的水。现在,Serverville 的某个人拉动了大杠杆,水(数据)从 Serverville 流向 Clientville。 Serverville 发送完所有想要发送的水后,它会关闭控制杆,河床将再次变空(并且实际上随着连接关闭而被破坏)。这就是 Clientville 得到 -1 的地方。现在想象一下,一些推土机破坏了河床,一些水从未到达克伦特维尔。这就是“连接重置”的情况。
希望这有帮助:)
关于Java nio read() 返回-1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14153488/