簡體   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