nio 远程主机强迫关闭了一个现有的连接 解决方案

nio编程过程中会出现:

Exception in thread "main" java.io.IOException: 远程主机强迫关闭了一个现有的连接。
	at sun.nio.ch.SocketDispatcher.read0(Native Method)
	at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:25)
	at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:233)
	at sun.nio.ch.IOUtil.read(IOUtil.java:206)
	at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:207)
	at com.rb.socket.nio.server.n.NIOServer.handleKey(NIOServer.java:87)
	at com.rb.socket.nio.server.n.NIOServer.listen(NIOServer.java:57)
	at com.rb.socket.nio.server.n.NIOServer.main(NIOServer.java:122)

 

 

 

主要原因是:客户端自己关闭了连接(没有调用SocketChannel的close方法),服务器还在read事件中,这个时候读取客户端的时候会报错。

 

解决办法,在客户端合适的时候,调用SocketChannel的close方法,同时服务器读取事件增加如下逻辑:

count = client.read(receivebuffer);
   if(count==-1){
    System.out.println(count);
    client.close();
   } else {

如果服务器没有client.close,则一直System.out.println(count)

 

 

所以先客户端调用close,然后服务器在read事件里面读取返回是不是-1,如果是,调用服务器这边客户端的引用的close方法,这样两边的SocketChannel都关闭了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的使用NIO写的服务端示例代码: ```java import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; public class NIOServer { private Selector selector; public void initServer(int port) throws IOException { // 创建一个选择器 selector = Selector.open(); // 创建一个服务端通道 ServerSocketChannel serverChannel = ServerSocketChannel.open(); // 配置为非阻塞模式 serverChannel.configureBlocking(false); // 绑定端口 serverChannel.socket().bind(new InetSocketAddress(port)); // 注册到选择器并监听连接事件 serverChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("Server start on " + port + "..."); } public void listen() throws IOException { while (true) { // 阻塞直到有事件发生 selector.select(); // 处理事件 Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = keys.next(); keys.remove(); // 如果是新连接事件 if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel channel = server.accept(); channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_READ); System.out.println("New connection from " + channel.getRemoteAddress()); } // 如果是读事件 else if (key.isReadable()) { SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); channel.read(buffer); String msg = new String(buffer.array()).trim(); System.out.println("Receive message from " + channel.getRemoteAddress() + ": " + msg); } } } } public static void main(String[] args) throws IOException { NIOServer server = new NIOServer(); server.initServer(8888); server.listen(); } } ``` 这个服务端使用了Java NIO的API,可以监听端口,接受客户端连接,并读取客户端发送的消息。稍作修改也可以实现回复客户端消息的功能。需要注意的是,由于NIO是非阻塞的,所以需要在事件到来时进行处理,否则会阻塞线程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值