Java NIO服务器:远程主机强迫关闭了一个现有的连接
程序员文章站
2022-03-02 15:28:36
...
Java NIO聊天室中,若客户端强制关闭,服务器会报“java.io.IOException: 远程主机强迫关闭了一个现有的连接。”,并且服务器会在报错后停止运行,错误的意思就是客户端关闭了,但是服务器还在从这个套接字通道读取数据,便抛出IOException,导致这种情况出现的原因就是,客户端异常关闭后,服务器的选择器会获取到与客户端套接字对应的套接字通道SelectionKey,并且这个key的兴趣是OP_READ,执行从这个通道读取数据时,客户端已套接字已关闭,所以会出现“java.io.IOException: 远程主机强迫关闭了一个现有的连接”的错误。解决这种问题也很简单,就是服务器在读取数据时,若发生异常,则取消当前key并关闭通道,如下代码:
因在catch中取消了key,readMsg返回后,run方法继续往下走,之前的代码会报“java.nio.channels.CancelledKeyException”错误,所以需要判断当前key是否有效,
之前的代码:
修复后的代码:
这样改良之后的聊天室服务端,客户端异常强制关闭后,服务器便会妥善处理了,也不会报错,更不会停止运行。改良之后还算比较稳定运行的。
参考资料:[url]http://blog.csdn.net/abc_key/article/details/29295569[/url]
//获取此key对应的套接字通道
SocketChannel channel = (SocketChannel) key.channel();
//创建一个大小为1024k的缓存区
ByteBuffer buffer = ByteBuffer.allocate(1024);
StringBuffer sb = new StringBuffer();
//将通道的数据读到缓存区
int count = 0;
try{
count = channel.read(buffer);
}catch(IOException e){
key.cancel();
channel.socket().close();
channel.close();
return;
}
因在catch中取消了key,readMsg返回后,run方法继续往下走,之前的代码会报“java.nio.channels.CancelledKeyException”错误,所以需要判断当前key是否有效,
之前的代码:
//若此key的通道的行为是"读"
if (key.isReadable()) {
readMsg(key);
}
//若次key的通道的行为是"写"
if (key.isWritable()) {
writeMsg(key);
}
修复后的代码:
//若此key的通道的行为是"读"
if (key.isValid() && key.isReadable()) {
readMsg(key);
}
//若次key的通道的行为是"写"
if (key.isValid() && key.isWritable()) {
writeMsg(key);
}
这样改良之后的聊天室服务端,客户端异常强制关闭后,服务器便会妥善处理了,也不会报错,更不会停止运行。改良之后还算比较稳定运行的。
参考资料:[url]http://blog.csdn.net/abc_key/article/details/29295569[/url]
上一篇: (一)NIO与BIO
下一篇: JPA(六)多对多
推荐阅读
-
Python中使用pip安装库时提示:远程主机强迫关闭了一个现有的连接
-
Adb connection Error:远程主机强迫关闭了一个现有的连接
-
Adb connection Error:远程主机强迫关闭了一个现有的连接
-
Python中使用pip安装库时提示:远程主机强迫关闭了一个现有的连接
-
关于java.io.IOException: 远程主机强迫关闭了一个现有的连接问题解决
-
[Redis] 解决 java.io.IOException: 远程主机强迫关闭了一个现有的连接
-
Netty学习4—NIO服务端报错 远程主机强迫关闭了一个现有的连接
-
elasticsearch java.io.IOException: 远程主机强迫关闭了一个现有的连接。
-
使用Redisson与SpringBoot时出现java.io.IOException: 远程主机强迫关闭了一个现有的连接异常
-
解决springboot2整合Redis 后某个接口报错 java.io.IOException: 远程主机强迫关闭了一个现有的连接