Java NIO服务器:远程主机强迫关闭了一个现有的连接

来源:互联网 发布:程序员要懂软件架构吗 编辑:程序博客网 时间:2024/06/04 18:44

转自:http://blog.csdn.net/abc_key/article/details/29295569

Java NIO服务器:远程主机强迫关闭了一个现有的连接

标签: Java NIO强制关闭异常远程主机强制关闭了一个现有连接
 7127人阅读 评论(0) 收藏 举报
 分类:

Java NIO聊天室 中,若客户端强制关闭,服务器会报“Java.io.IOException: 远程主机强迫关闭了一个现有的连接。”,并且服务器会在报错后停止运行,错误的意思就是客户端关闭了,但是服务器还在从这个套接字通道读取数据,便抛出IOException,导致这种情况出现的原因就是,客户端异常关闭后,服务器的选择器会获取到与客户端套接字对应的套接字通道SelectionKey,并且这个key的兴趣是OP_READ,执行从这个通道读取数据时,客户端已套接字已关闭,所以会出现“java.io.IOException: 远程主机强迫关闭了一个现有的连接”的错误。解决这种问题也很简单,就是服务器在读取数据时,若发生异常,则取消当前key并关闭通道,如下代码:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //获取此key对应的套接字通道  
  2. SocketChannel channel = (SocketChannel) key.channel();  
  3. //创建一个大小为1024k的缓存区  
  4. ByteBuffer buffer = ByteBuffer.allocate(1024);  
  5. StringBuffer sb = new StringBuffer();  
  6. //将通道的数据读到缓存区  
  7. int count = 0;  
  8. try{  
  9.     count = channel.read(buffer);  
  10. }catch(IOException e){  
  11.     key.cancel();  
  12.     channel.socket().close();  
  13.     channel.close();  
  14.     return;  
  15. }  

因在catch中取消了key,readMsg返回后,run方法继续往下走,之前的代码会报“java.nio.channels.CancelledKeyException”错误,所以需要判断当前key是否有效,

之前的代码:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //若此key的通道的行为是"读"  
  2. if (key.isReadable()) {  
  3.     readMsg(key);  
  4. }  
  5. //若次key的通道的行为是"写"  
  6. if (key.isWritable()) {  
  7.     writeMsg(key);  
  8. }  
修复后的代码:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //若此key的通道的行为是"读"  
  2. if (key.isValid() && key.isReadable()) {  
  3.     readMsg(key);  
  4. }  
  5. //若次key的通道的行为是"写"  
  6. if (key.isValid() && key.isWritable()) {  
  7.     writeMsg(key);  
  8. }  
这样改良之后的聊天室服务端,客户端异常强制关闭后,服务器便会妥善处理了,也不会报错,更不会停止运行。改良之后还算比较稳定运行的。
0 0
原创粉丝点击