[英]Java nio read() return -1
这不是我第一次尝试了解这个问题,但我希望它将是最后一个:
一些背景:
我有一个以非阻塞模式工作的Java SocketChannel NIO
服务器。
该服务器具有多个客户端,可以从该客户端发送和接收消息。
每个客户端每隔一段时间就会通过"keepalive"
消息维护其与服务器的连接。 服务器的主要思想是客户端将始终保持连接,并以“推送”模式从中接收消息。
现在我的问题是:
在Java NIO中, read()
函数-当read()返回-1时-表示其EOS。
在这里我提出的问题中,我意识到这意味着套接字已完成其当前流,不需要关闭。
当在谷歌搜索更多有关此的时候,我发现这确实意味着该连接在另一侧是关闭的。
“流”一词到底是什么意思? 是客户端发送的当前消息吗? 客户端连接是否可以发送更多消息?
如果客户端从未告诉过SocketChannel
为什么它会在客户端关闭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()return -1和对等I / O错误重置连接有什么区别?
当read()返回-1时,这仅表示当前流中没有更多数据。 连接重置意味着可能有更多数据,但是该连接不再存在,因此无法再读取该数据。 再次对河流进行分析:将数据想象为使用连接两个村庄(连接)的河床从上游村庄(又名Serverville)向下游村庄(又名Clientville)发送的水。 现在,Serverville的某个人发挥了重要作用,水(数据)从Serverville流到Clientville。 Serverville已发送完所有要发送的水后,它将关闭杠杆,河床将再次变空(并在连接关闭时实际上被销毁了)。 这是Clientville获得-1的地方。 现在想象一下,一些推土机打断了河床,而有些水却从未流到Clientville。 这是“连接重置”情况。
希望这可以帮助 :)
“流”一词到底是什么意思? 是客户端发送的当前消息吗?
它是字节流,而不是消息。 您可以使用这些字节来形成消息,但是流不知道您正在执行此操作,也不以任何方式支持消息。
如果客户端从未告诉过SocketChannel,为什么它会在客户端关闭SocketChannel?
如果另一端将其关闭,则只能以-1关闭它。
read()return -1和对等I / O错误重置连接有什么区别?
您可以通过其他方式关闭或断开连接,例如从同一侧将其关闭,或者连接超时(例如,拔出网络电缆)。
顺便说一句:您编写代码的方式更适合于阻止NIO。 例如,如果您收到一条以上的完整消息,则丢弃第一条消息之后的所有内容。 如果使用阻塞IO并保留所有已阅读内容,则不会损坏或丢弃消息。
- “流”一词到底是什么意思? 是客户端发送的当前消息吗?
它基本上意味着连接的一侧,即全双工。 TCP是字节流协议,提供两个独立的字节流,每个方向一个。
- 如果客户端从未告诉过SocketChannel,为什么它会在客户端关闭?
不会的。 客户端确实关闭了连接。 这就是read()
返回-1的意思。
read()return -1和对等I / O错误重置连接有什么区别?
read()
返回-1表示对等方正确关闭了连接。 “由对等方重置连接”表示某种协议错误,通常是您已将数据写入到已被对等方关闭的连接中。
重新编写代码,如果read()
返回-1,则必须关闭通道。 没有其他明智的方法可以进行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.