2013-02-01 65 views
3

我有一個在Windows XP和Windows 7上運行的Java應用程序。 此應用程序有一個開放的tcp連接到另一臺計算機。java應用程序TCP連接丟失檢測在Windows 7中有所不同?

現在來說一點:在一臺XP機器上,通過返回-1或SocketException,拔掉網線對我的inputstream.read方法幾乎會產生一點影響。我如何檢測網絡連接丟失是一回事。在Win7計算機上拔掉網線時,Windows本身告訴我這是在任務欄的連接圖標中,但是我的Java應用程序沒有得到任何提示。它保持好像什麼都沒有發生。

TCP在Windows 7上的行爲不同嗎?或者Windows 7是否將這些信息從其應用程序中屏蔽掉?在Windows XP輪後約5秒

package tcpconnectionlossdetectiontest; 

import java.io.IOException; 
import java.io.InputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.SocketException; 
import java.net.SocketTimeoutException; 

public class TcpListener extends Thread { 
    private int _portNo = 23456; 
    private boolean _done = false; 

    public static void main(String[] args) { 
    int port = 23456; 

    if (args.length > 0) { 
     int position = -1; 
     do { 
     String arg = args[++position].trim(); 
     if (arg.equalsIgnoreCase("-p") || arg.equalsIgnoreCase("--PortNo")) { 
      String argParameter = args[++position].trim(); 
      // e.g. store additional argument 
      try { 
      port = Integer.parseInt(argParameter); 
      } catch (NumberFormatException nfex) { 
      port = 23456; 
      } 
      System.out.println("Argument " + position + " (" + arg + ", " + argParameter + "): port number set to " + port); 
     } else { 
      System.out.println("Argument " + position + " (" + arg + ") unknown."); 
     } 
     } 
     while (position + 1 < args.length); 
     // Parsing command line arguments ready. 
    } 

    TcpListener listener = new TcpListener(port); 
    listener.start(); 
    } 

    public TcpListener(int portNo) { 
    this._portNo = portNo; 
    } 

    public void run() { 
    Socket s = null; 
    InputStream is = null; 
    byte[] buf = new byte[1000]; 
    int readResult = 0; 
    int maxOpen = 3; 
    int openCounter = 0; 
    try { 
     ServerSocket sSocket = new ServerSocket(this._portNo); 
     while (openCounter < maxOpen) { 
     if (s == null) { 
      try { 
      System.out.println("waiting for connection on port " + this._portNo); 
      sSocket.setSoTimeout(60000); 
      s = sSocket.accept(); 
      if (s != null) { 
       System.out.println("got connection on port " + this._portNo); 
       openCounter++; 
       is = s.getInputStream(); 
      } 
      } catch (SocketTimeoutException stex) { 
      System.out.println("no connection yet..."); 
      } 
     } 
     if (s != null && is != null) { 
      readResult = is.read(buf, 0, 1000); 
     } 
     if (readResult == -1) { 
      readResult = 0; 
      System.out.println("connection broken..."); 
      is=null; 
      if (s != null) { 
      s.close(); 
      s=null; 
      } 
     } else if (readResult > 0) { 
      System.out.println("Data read: " + new String (buf,0,readResult)); 
     } 
     } 
    } catch (IOException ioex) { 
     System.out.println("IO exception caught:"); 
     ioex.printStackTrace(); 
    } 
    this._done = true; 
    } 
} 

結果後斷開是:在Windows 7上

waiting for connection on port 23456 
no connection yet... 
waiting for connection on port 23456 
got connection on port 23456 
Data read: Here is a connection from win7 to xp... 
Data read: 

IO exception caught: 
java.net.SocketException: Connection reset 
    at java.net.SocketInputStream.read(SocketInputStream.java:168) 
    at tcpconnectionlossdetectiontest.TcpListener.run(TcpListener.java:73) 
Process exited with exit code 0. 

結果斷開後是:什麼都沒有。應用程序保持打開狀態,無需斷開連接檢測

@edit 2013-02-01 09:54:發生在jre6和jre7。

@edit 2013-02-01 10:59:發生在32位和64位的Java。發生在Win7筆記本電腦和普通PC上。

@edit 2013-02-01 12:40:添加了代碼示例和結果。

@edit 2031-02-06:因爲我在互聯網上沒有找到任何東西,也沒有人爲此提供解決方案,所以我在應用程序中添加了一個主動乒乓機制。現在我可以在最多20秒後檢測到。連接中斷。

@edit 2013-02-08:瞭解狀態的另一種方法是'netsh interface ip show interfaces',但命令行結果必須在知道狀態之前在java中解析。也許有更好的方法來獲取這些信息。

+0

你能提供一個簡約的代碼示例,我們可以部署調查問題? – sulai

+0

我將不得不寫一個。給我一點時間...... – GVerse

+0

似乎Windows 7以某種方式在斷開斷開連接時緩衝tcp數據,而不是告訴應用程序已斷開連接。有沒有辦法來禁用這個? – GVerse

回答

0

Win7上的TCP/IP與XP上的實現不同。一個重要的問題是它包含了他們稱之爲自動調整的內容。它旨在優化吞吐量等,但可能會將連接狀態更改傳遞給JVM,從而產生意想不到的副作用。

退房這裏獲取更多信息,包括如何將其關閉線程: http://social.technet.microsoft.com/Forums/en-US/w7itpronetworking/thread/1a6197df-ada7-4b12-92b7-a8a2f454f9a3

+0

似乎沒有連接到像自動調整,因爲這隻改變接收緩衝區大小。我也試過'netsh int ip set global taskoffload = disabled'。我甚至將套接字綁定到LAN接口進行測試,沒有任何幫助。 – GVerse

相關問題