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 クライアントは 3 番目で最後の NetBIOS 名要求を送信し、サーバーは同じ ICMP 応答を返します。その1.5秒後にようやくソケットデータが送信されます。

したがって、Windows はサーバーの NetBIOS 名を判別するために 3 回試行し、毎回 1.5 秒待機するようです。最終的に (4.5 秒後)、あきらめてデータを送信します。これは、あなたが報告した 4 ~ 5 秒の一時停止を説明していると思います。

一時停止を解消する 1 つの回避策は、サーバーの「hosts」ファイル エントリを追加することです。(そのファイル内で使用するホスト名は実際には問題ではありません。単に IP アドレスが存在するだけで、NetBIOS の名前解決の必要がなくなります。)おそらく他の代替手段もあります (たとえば、サーバー名を WINS や DNS などに追加するなど)。 、名前解決に使用している Windows マシンによって異なります)。

于 2015-08-13T05:00:23.787 に答える
0

あなたは書くことについて不平を言っていて、読むコードだけを示しています。書き込みコードはどのように見えますか? スタックでバッファリングされたストリームまたはライターを使用していない場合SSLSocket、最大 44 倍のデータ サイズの爆発が発生する可能性があり、パフォーマンスに深刻な影響を与える可能性があります。数年前にインターネット上で大規模なテストを行った結果、適切に記述されたコードを使用すれば、SSL はプレーンテキストの 3 倍も遅くないという結論に達しました。

于 2013-03-28T08:56:24.717 に答える