2

服务器: Linux

测试客户端: OS X、CentOS、Windows

服务器/客户端编程语言: Java

Server-side

SSLServerSocketFactory sslserversocketfactory =
                (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket sslserversocket =
                (SSLServerSocket) sslserversocketfactory.createServerSocket(9999);
SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();

InputStream inputstream = sslsocket.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

String string = null;
while ((string = bufferedreader.readLine()) != null) {
    System.out.println(string);
    System.out.flush();
}

使用此选项执行的服务器程序

-Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456

证书:在 Linux 上使用 keytool 创建

keytool -genkey -keystore mySrvKeystore -keyalg RSA

客户端

....
    SocketAddress sa = new InetSocketAddress(ip, port);
....
    SSLContext sslContext = SSLContext.getInstance("SSL");
....
      sslContext.init(.........., new SecureRandom());

      SSLSocketFactory socketFactory = sslContext.getSocketFactory();
      this.clientSock = socketFactory.createSocket();
      this.clientSock.connect(sa, this.ConnectTimeout);       
      this.clientSock.setSoTimeout(this.RecvTimeout);
      this.clientSock.setReuseAddress(true);
....

public boolean writeTo(String procname, BufferedOutputStream out, byte[] data)
{....
    out.write(data, 0, data.length);
    out.flush();
....}

结果:一切正常,但只有来自 Windows 的客户端程序,写入输出流时会延迟。

  1. 已建立 SSL 套接字连接
  2. 设置输出/输入流
  3. 将数据写入输出流
  4. 冲洗

... 4-5 秒后,它无缘无故地卡在了这里...

  1. 关闭

延迟发生在从 Windows 7、Windows XP 执行的同一个 java 客户端简单程序上。从 3 台不同的 Windows 机器测试。其他地方都很好。

所以我尝试用 C 和 PHP 构建 SSL 简单客户端,在 Windows 上效果很好。这意味着只有 Java 客户端方法不起作用。

有没有人有任何想法或类似的经验?我看过一些怀疑 WINS/DNS 的帖子,但这里的情况似乎并非如此。有趣的是,每台 Windows 机器总是有大约 4-5 秒的延迟。

非常感谢您提前提出的意见。

4

2 回答 2

1

我遇到过类似的问题。使用 tcpdump,我发现从客户端到服务器的 TCP 连接(SYN、SYN-ACK、ACK)几乎是瞬间发生的,然后是一个神秘的暂停,然后客户端实际发送数据。

tcpdump 输出表明,在连接后,客户端(在 Windows 上运行)立即发送 NetBIOS 名称请求(大概是为了找出服务器的名称,也许它可以选择适当的证书或其他东西)并且服务器立即回复说明 NetBIOS UDP (137) 端口无法访问的 ICMP 响应。看起来 Windows 客户端忽略了该响应。1.5 秒后,Windows 客户端发送另一个 NetBIOS 名称请求,服务器发送相同的 ICMP 响应。再过 1.5 秒后,Windows 客户端发送第三个也是最后一个 NetBIOS 名称请求,服务器发回相同的 ICMP 响应。套接字数据最终在 1.5 秒后传输。

所以看起来windows尝试了3次来确定服务器的NetBIOS名称,每次等待1.5秒。最终(4.5 秒后)它放弃并发送数据。我认为这解释了您报告的 4-5 秒暂停。

消除暂停的一种解决方法是为服务器添加一个“主机”文件条目。(在该文件中使用什么主机名并不重要。IP 地址的存在避免了对 NetBIOS 名称解析的需要。)可能还有其他选择(例如,将服务器名称添加到 WINS 或 DNS 或其他东西,取决于您的 Windows 机器用于名称解析的内容)。

于 2015-08-13T05:00:23.787 回答
0

你在抱怨写作,你只是在显示阅读代码。编写代码是什么样的?如果您没有在堆栈中使用缓冲流或写入器,SSLSocket您可能会获得高达 44 倍的数据大小爆炸,这将严重影响性能。几年前,我在 Internet 上进行了一些广泛的测试,得出的结论是,使用正确编写的代码,SSL 的速度不会比明文慢 3 倍。

于 2013-03-28T08:56:24.717 回答