【问题标题】:socket mac os x vs windows java slow套接字 mac os x 与 windows java 慢
【发布时间】:2024-01-17 09:37:01
【问题描述】:

请帮我弄清楚为什么 Mac OS X Java 的运行时间是 Windows XP Java 的 5 倍。

我有一些代码在 Mac 和 PC Java 上表现不同。我有一个 Java GUI,可以与 Windows XP 机器上的多个“服务器”通信。

当我在另一台 Windows XP 机器或 linux 机器上运行 GUI 时,LabView 会收到消息并在 1 秒内做出响应。

当它从 Mac OS X 机器上运行时,需要 5 秒。暂停似乎是(从我们可以看出的调试中)我认为我发送字符串“pot 7\r\n”和 LabView 实际接收到它的时间之间。

当来自 Windows 时,LabView 会立即看到 pot 7 命令(我们有一个显示器要检查),但根据 LabView 程序员的说法,当从 Mac OS 机器发送时,该命令直到 5 秒过去后才会显示在屏幕上.

我会尽量在这里提供足够多的代码,让知道更多的人可能会说啊哈!

String IPaddress;
int commPort;
BufferedReader reader;
PrintWriter writer;
Socket sock;
long timeout = 8000;

...

public synchronized void connectCommPort() {
    if (commportconnected != true) {
        try {
            sock = new Socket();
            InetSocketAddress endpoint = new InetSocketAddress(IPaddress, commPort);
            sock.connect(endpoint, timeout);
            sock.setSoTimeout( timeout );
            reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
            writer = new PrintWriter(sock.getOutputStream());
            commportconnected = true;
            errorstatus = false;
        } catch (IOException ex) {
            logwriter("LabV: WARNING - network connection to Labview command port failed."+ex.toString());
            commportconnected = false;
            errorstatus = true;
        }
    }
}

...

public synchronized float[] readpots() {

    String message = "pot 7";
    connectCommPort();

    if (commportconnected) {
        try {
            writer.print(message + "\r\n");
            writer.flush();
            logwriter("LabV: [sent] " + message);

            shortpotvalues = potslistener();
        } catch (Exception ex) {
        }
        disconnectCommPort();
    }
    potvalues[0] = shortpotvalues[0];
    potvalues[1] = shortpotvalues[1];
    potvalues[2] = shortpotvalues[2];
    potvalues[3] = shortpotvalues[3];
    potvalues[4] = shortpotvalues[4];
    potvalues[5] = shortpotvalues[5];
    potvalues[6] = shortpotvalues[6];
    potvalues[7] = 5.0f;


    return potvalues;
}

public synchronized float[] potslistener() {

    String message = null;
    int i = 0;
    try {
        //while ((message = reader.readLine()) != null && i < shortpotvalues.length) {
        while (i < shortpotvalues.length) {
            message = reader.readLine();
            if ( message != null )
            {
                logwriter("LabV: [received] " + message);
                if (message.contains(".")) 
                {
                    shortpotvalues[i] = Float.parseFloat(message);
                    i++;
                }
            }
            else
            {
                logwriter("LabV: received NULL unexpectedly, may not have all pots correct");
            }
        }  // close reader-ready-while
    } catch (ArrayIndexOutOfBoundsException aiofbex) {
        logwriter("LabV: in potslistener() Array out of bounds! " + aiofbex.toString());
    } catch (Exception ex) {
        logwriter("LabV: in potslistener() got exception: " + ex.toString());
    }
    return shortpotvalues;
}

在 Mac OS X 10.8 上。运行 java -version 给出:

marks-Mac-mini:~ mark$ java -version
java version "1.6.0_43"
Java(TM) SE Runtime Environment (build 1.6.0_43-b01-447-11M4203)
Java HotSpot(TM) 64-Bit Server VM (build 20.14-b01-447, mixed mode)

在 Windows XP 上(当 GUI 在 windows 上运行并且工作正常时使用的 java)给出:

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\gus>java -version
java version "1.7.0_07"
Java(TM) SE Runtime Environment (build 1.7.0_07-b10)
Java HotSpot(TM) Client VM (build 23.3-b01, mixed mode, sharing)

最后这里是来自 PC 的部分日志:

2013-03-19T11:45:22.000 LabV: [sent] pot 7
2013-03-19T11:45:22.921 LabV: [received] 2.310835
2013-03-19T11:45:22.921 LabV: [received] 2.447397

相应地来自 Mac(注意发送和第一次接收之间的 5 秒):

2013-03-13T12:13:17.092 LabV: [sent] pot 7
2013-03-13T12:13:22.513 LabV: [received] 2.300508
2013-03-13T12:13:22.514 LabV: [received] 2.112090

提前感谢任何帮助/建议。

跟进:

我后来发现,如果我使用具有相同 Java 的 10.7.5 Mac OS 机器,速度与 Windows XP 相同。我现在正在调查 10.8.3 和网络和/或安全防火墙设置的问题。再次感谢任何帮助。

【问题讨论】:

  • 你可以尝试禁用nagle算法:socket.setTcpNoDelay(true)
  • 感谢您的想法。但这没有帮助。
  • 我怀疑它是 PrintWriter 自动刷新 导致问题,即使你 flush() 强行。您可以尝试直接写入流而不是PrintWriter,例如socket.getOutputstream().write((message+"\r\n").getBytes("utf-8")); socket.getOutputstream().flush();
  • 大家好。这种情况对我们来说已经很严重了,我们不知道为什么会发生这种情况。我为 LabV 端编写了一个 Java 模拟器,模拟器响应很快,所以它不是网络错误。延迟发生在 LabView 代码和读取电位器的安捷伦设备之间。我们认为问题与 Agilent 或 LabView 中的实现有关,即当我们在没有 DNS 的封闭网络中时,DNS 查找是否发生在旧代码中。我们正在考虑建立一个 DNS 以查看是否是这种情况。感谢您的帮助。

标签: java windows performance osx-lion osx-mountain-lion


【解决方案1】:

也许这会帮助别人。

当在隔离网络上运行时,这个问题就成了问题。在完成所有这些工作(模拟器、输出流、禁用 bonjour 等)之后,解决方案是在 Microsoft Windows XP 机器上编辑主机文件。

我认为这很有效,因为没有时间花在寻找 WINS 或 DNS 服务器上。令人讨厌的是,在同一网络上的 mac 或 linux 机器上,寻址 IP 地址会自动消除任何导致超时的 DNS 调用。编辑文件完全消除了奇怪的延迟。当我再次访问机器时,我会更具体地说明所做的编辑。

导致我们出现此问题的调试是注意到一些需要很长时间才能响应的 netbios 请求。他们看到这个的时候我不在。我的理解是他们在 mac os 机器上运行了一个数据包嗅探器并看到了这些请求。当他们编辑 Windows 机器主机文件时,问题就消失了(它可以找到没有 netbios 广播的 mac)。

“经过一些数据包嗅探后,我们确定了我们已经确定的延迟 从 GUI 查询安捷伦时遇到的问题是由于 到 [Windows XP 机器] 寻找安捷伦 [a 电机控制器] 通过 WINS 服务。不能说我完全 了解发生了什么,但我们验证了延迟消失了 当我们关闭 NetBIOS 服务时。

这一切都很好,除了 Windows 文件共享似乎依赖于 NetBIOS 服务,因此 没有它,我们无法访问 [Windows XP 机器] 上的磁盘。

所以我们在宿主文件中添加了两行"

这是我同事发给我的。所以它与我的 java 代码相距两个系统......我在 Windows XP 机器上处理了一个 LabView 应用程序。我为 LabView 应用程序编写了一个模拟器。但网络问题出在 LabView 应用程序和另一台设备之间。所以他的解决方法是在Windows\System32\Drivers\etc\hosts中放两行,解决Mac和安捷伦在Windows端的问题,网络延迟就消失了!

【讨论】: