Java 应用程序 tcp 连接丢失检测在 Windows 7 中有所不同?

标签 java windows-7 tcp connection detect

我有一个在 Windows XP 和 Windows 7 上运行的 Java 应用程序。 此应用程序与另一台计算机有一个开放的 tcp 连接。

现在重点来了:在 XP 机器上,拔下网络电缆对我的 inputstream.read 方法几乎立即产生影响,返回 -1 或 SocketException。这是我检测网络连接丢失的方式之一。在 Win7 机器上,当网络电缆被拔掉时,Windows 本身会在任务栏的连接图标中告诉我这一点,但我的 Java 应用程序没有得到任何提示。就好像什么都没发生过一样。

TCP 在 windows 7 上的行为是否不同,或者 windows7 是否将此信息从其应用程序中屏蔽掉?

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;
  }
}

断开连接后约 5 秒后在 windows xp 上的结果是:

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.

断开连接后在 Windows 7 上的结果是:... 没有。应用程序在没有断开连接检测的情况下保持打开状态。

@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 中解析命令行结果。也许有更好的方法来获取该信息。

最佳答案

Win7 上的 TCP/IP 与 XP 上的实现不同。一个重要的问题是它包含一种他们称之为自动调整的东西。它旨在优化吞吐量等,但将连接状态更改传递给 JVM 可能会产生意想不到的副作用。

查看此处的线程以获取更多信息,包括如何将其关闭: http://social.technet.microsoft.com/Forums/en-US/w7itpronetworking/thread/1a6197df-ada7-4b12-92b7-a8a2f454f9a3

关于Java 应用程序 tcp 连接丢失检测在 Windows 7 中有所不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14641552/

相关文章:

linux - VirtualBox Linux 不返回 ping 并且主机无法访问该 guest 上的 apache

c++ - 不再能够最大化 CPU

c++ - 将 double 转换并连接到字节数组

VB.NET - 来自 TCP 客户端的数据不按顺序

Java TCP 服务器在发送所有行时收到来自客户端的每一行

java - TSV 文件转换为 RDF

java - 安卓错误: Attempt to invoke virtual method 'java.lang.String android.content.Intent.getStringExtra(java.lang.String)' on a null object reference

.net - 确定哪个 w3wp.exe 进程属于 Windows 7/IIS7.5 中的哪个 App Pool?

java - 图形 (java.awt.Graphics) 无法在调用时工作

java - 如何将 mysql 连接器添加到 Sqoop 1.99.3