我有一個在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中解析。也許有更好的方法來獲取這些信息。
你能提供一個簡約的代碼示例,我們可以部署調查問題? – sulai
我將不得不寫一個。給我一點時間...... – GVerse
似乎Windows 7以某種方式在斷開斷開連接時緩衝tcp數據,而不是告訴應用程序已斷開連接。有沒有辦法來禁用這個? – GVerse