繁体   English   中英

Java NIO TCP超时问题

[英]Java NIO TCP timeout issue

我在2个线程中使用一个SocketChannel,一个线程用于发送数据,另一个线程用于接收数据。

SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(ip,port));
socketChannel.configureBlocking(false);

线程1:使用上述套接字通道写入数据

线程2:使用相同的套接字通道读取数据

我没有在socketchannel上使用任何选择器,因为我需要读写异步(使用2个不同的线程)

问题:当连接丢失时,socketchannel.write()和socketchannel.read()操作不会引发任何错误。 它只是阻止操作。

我需要检测连接丢失。

我尝试在线程2中使用心跳方法,但是由于读取操作只是阻塞,因此该方法不起作用。 还有其他方法可以在不使用新线程中的心跳的情况下检测连接丢失吗?

如果存在连接丢失,是否可能在写入/读取时引发错误?

提前致谢。

编辑:

线程1:

public void run() {
  socketChannel = SendAndReceivePacketUtil.createConnection(ip, port);
  socketChannel.configureBlocking(false);

  RecTask task = new RecTask(socketChannel);
  Thread recThread = new Thread(task);
  recThread.start();

  while(true)
  {
     byte[] data= getDataFromQueue(ip);
     if(data!= null) {
         //print(new String(data));
         sendPacket(data, socketChannel);
     }
   }
}

线程2:(RecTask)

public void run() {
  while(true) {
    byte[] data = receivePacket(socketChannel);
    //print(new String(data));
  }
}

线程1和2都有try-catch-finally块。 最后关闭套接字通道。

了sendpacket:

int dataSent = 0;
while (dataSent < data.length) {
    long n = socketChannel.write(buf);
        if (n < 0) {
            throw new Exception();
        }
        dataSent += (int) n;
 }

receivePacket:

int dataRec = 0;
byte[] data = new byte[length];
ByteBuffer buffer = ByteBuffer.wrap(data);

while (dataRec < length) {
    long n = socketChannel.read(buffer);
    if (n < 0) {
        throw new Exception();
    }
    dataRec += (int) n;
}       
return data;

我不断发送和接收数据。 但是,一旦连接断开,就不会打印任何内容,并且代码只会卡住。 它是android wifi直接应用程序。 对于连接丢失的情况,我只是关闭了wifi模块。

我没有在socketchannel上使用任何选择器,因为我需要读写异步(使用2个不同的线程)

那不是避免Selector.的原因Selector. 实际上,没有Selector.很难编写正确的非阻塞NIO代码Selector.

问题:当连接丢失时,socketchannel.write()和socketchannel.read()操作不会引发任何错误。 它只是阻止操作。

不,不是。 您处于非阻止模式。 它要么返回一个正整数,要么返回零,或者抛出一个异常。 哪有

我尝试在线程2中使用心跳方法,但是由于读取操作只是阻塞,因此该方法不起作用。

读取操作在非阻塞模式下不会阻塞。

还有其他方法可以在不使用新线程中的心跳的情况下检测连接丢失吗?

检测TCP中的连接丢失的唯一可靠方法是写入连接。 最终,这将引发IOException: connection reset. 但是由于缓冲,重试等原因,连接丢失后第一次不会发生这种情况。

如果存在连接丢失,是否可能在写入/读取时引发错误?

就是这样

这个问题有严重的错误。 您发布的代码不是真实的代码,或者不是您所描述的行为。 您需要发布更多内容,例如您的读写代码。

您可以在套接字上寻找启用TCP-KEEP alive选项。 在空闲连接上, keep-alive发送keep-alive消息,并且期望在TCP层进行确认。

如果TCP-KEEP存活失败,则下一次读/写操作将导致错误(ECONNRESET),可将其用作连接丢失的信号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM