Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SSL握手:为什么服务器端在服务器端ChangeCipherSpec和完成之间等待100毫秒以上?_Java_Tomcat_Ssl_Jsse_Sslcontext - Fatal编程技术网

Java SSL握手:为什么服务器端在服务器端ChangeCipherSpec和完成之间等待100毫秒以上?

Java SSL握手:为什么服务器端在服务器端ChangeCipherSpec和完成之间等待100毫秒以上?,java,tomcat,ssl,jsse,sslcontext,Java,Tomcat,Ssl,Jsse,Sslcontext,我正在用SSLSocketFactory编写一个简单的HTTP服务器,下面是我的Java代码: public static void main(String[] args) throws Exception { KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(TestEcho.class.getResourceAsStream("/localhost.pfx"), "****".to

我正在用SSLSocketFactory编写一个简单的HTTP服务器,下面是我的Java代码:

 public static void main(String[] args) throws Exception {
      KeyStore ks = KeyStore.getInstance("PKCS12");
      ks.load(TestEcho.class.getResourceAsStream("/localhost.pfx"),
              "****".toCharArray());
      KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
      kmf.init(ks, "****".toCharArray());
      SSLContext sslc = SSLContext.getInstance("TLS");
      sslc.init(kmf.getKeyManagers(), null, null);

      // try (ServerSocket server = new ServerSocket(4443)) {
      try (ServerSocket server = sslc.getServerSocketFactory().createServerSocket(4443)) {
           while (true) {
                Socket socket = server.accept();
                // ((SSLSocket) socket).getSession();
                socket.getInputStream().read();
                socket.getOutputStream().write("HTTP/1.1 200 OK\r\nContent-Length: 2\r\nConnection: close\r\n\r\nok".getBytes());
                socket.getOutputStream().flush();
           }
      }
 }
但性能远低于Tomcat Http11协议。我捕获TCP转储,发现服务器端ChangeCipherSpec和Finished之间存在100毫秒以上的间隔。但是当我连接到Tomcat时,就没有这样的差距了

以上代码的TCP转储为:

[127.0.0.1:1962 Connected at 00:58:21.718]
[127.0.0.1:1962 Sent at 00:58:21.718] // ClientHello
0000:0000  16 03 03 00 C3 01 00 00-BF 03 03 59 82 04 AD 44   ...........Y...D
...
0000:00C0  02 03 02 01 02 02 01 01                           ........        
[127.0.0.1:1962 Received at 00:58:21.781] // ServerHello & Certificate & ServerHelloDone
0000:0000  16 03 03 0B EB 02 00 00-4D 03 03 59 82 04 A8 14   ........M..Y....
...
0000:0BE0  12 0D 53 CB B6 20 64 BC-8E 77 3A 0F 0E 00 00 00   ..S.. d..w:.....
[127.0.0.1:1962 Sent at 00:58:21.812] // ClientKeyExchange
0000:0000  16 03 03 00 46 10 00 00-42 41 04 ED DD 67 FB 22   ....F...BA...g."
...
0000:0040  39 50 1F 50 F2 12 62 A7-3D C8 FE                  9P.P..b.=..     
[127.0.0.1:1962 Sent at 00:58:21.828] // Client ChangeCipherSpec
0000:0000  14 03 03 00 01 01                                 ......          
[127.0.0.1:1962 Sent at 00:58:21.828]  // Client Finished
0000:0000  16 03 03 00 50 8E DB DC-39 07 9B 68 36 17 BB 44   ....P...9..h6..D
...
0000:0050  B3 5E 91 FF E8                                    .^...           
[127.0.0.1:1962 Received at 00:58:21.890] // Server ChangeCipherSuite
0000:0000  14 03 03 00 01 01                                 ......          
[127.0.0.1:1962 Received at 00:58:22.046] // Server Finished, but delayed 156ms !!!
0000:0000  16 03 03 00 50 71 68 70-ED 8F D6 73 11 94 DD F4   ....Pqhp...s....
0000:0010  D9 A4 1F 60 BA 48 43 B0-4B 53 EF 66 E5 59 F2 8B   ...`.HC.KS.f.Y..
0000:0020  DD CE D7 D5 8F C4 68 A2-87 07 92 A9 3B D9 9B 3B   ......h.....;..;
0000:0030  DD DE 1A 71 6F 87 8D 59-17 6F 8F 94 2C 89 01 DA   ...qo..Y.o..,...
0000:0040  E9 7D 08 E2 F2 FC 54 BF-FA 8D 45 F8 7B B0 29 8D   .}....T...E.{.).
0000:0050  CE 87 CF 81 E1                                    .....           
[127.0.0.1:1962 Sent at 00:58:22.046] // HTTP Request
0000:0000  17 03 03 00 A0 73 85 EE-93 BC 66 94 76 6D 49 74   .....s....f.vmIt
...
0000:00A0  DE C2 BE DD 46                                    ....F           
[127.0.0.1:1962 Received at 00:58:22.062] // HTTP Response
0000:0000  17 03 03 02 70 E8 CF 13-B4 E0 4F 32 8E 6F 37 74   ....p.....O2.o7t
...
0000:0270  DD 5B FB 99 9D                                    .[...           
[127.0.0.1:1962 Sent at 00:58:22.062] // Disconnect
0000:0000  15 03 03 00 40 42 BC E5-B7 B2 E4 B5 22 D2 DF 75   ....@B......"..u
...
0000:0040  B8 59 B2 89 FB                                    .Y...           
[127.0.0.1:1962 Disconnected at 00:58:22.062]
在对Tomcat服务器的测试中,TCP转储类似于:

...
[127.0.0.1:1968 Received at 00:58:50.312] // server-side ChangeCipherSpec & Finished
0000:0000  14 03 03 00 01 01 16 03-03 00 50 03 0D D0 FE 94   ..........P.....
0000:0010  5D 0B 22 60 62 46 F3 29-D9 37 B7 D1 42 60 5A 6A   ]."`bF.).7..B`Zj
0000:0020  93 C8 1F CF D8 B9 81 7D-DD 3D A9 1E A0 F0 C0 05   .......}.=......
0000:0030  11 C8 C4 B9 31 16 E5 1E-2F 43 EA 45 2A F0 E8 BF   ....1.../C.E*...
0000:0040  9E BD 20 84 8E 5A 1A 57-0B 31 32 BE 5E 6C B3 F3   .. ..Z.W.12.^l..
0000:0050  6A 00 95 D3 75 32 03 35-83 3D 12                  j...u2.5.=.     
...

我的Java代码中的SSLContext、KeyManager或SSL握手是否存在使用问题?

阅读tomcat的源代码后,我只需启用TCP\u节点延迟即可消除延迟:

更新-1

tomcat为每个接受的套接字启用TCP_节点延迟。请参阅tomcat coyote的源代码8.0.x org.apache.tomcat.util.net.SocketProperties第155行:

/**
 * TCP_NO_DELAY option. JVM default used if not set.
 */
protected Boolean tcpNoDelay = Boolean.TRUE;
和2个setProperties方法,一旦接受套接字就调用

更新-2

JVM默认禁用TCP_节点延迟,这意味着Nagle的算法可以延迟发送小字节。很明显,服务器完成被Nagle算法延迟了


谷歌可以搜索到很多关于TCP_NODELAY的文章。

如果默认情况下启用了它,启用它如何修复它?或者改变什么?对不起。已更改为tomcat为每个接受的套接字启用TCP_节点延迟相同的问题。没有任何变化,无论是在插座上还是在实质上,在你的回答中。如果已经启用,启用它如何解决问题?但JVM在默认情况下禁用TCP_节点延迟,这意味着Nagle的算法可以延迟发送小字节。显然,服务器完成是由Nagle的算法延迟的。谷歌可以搜索到很多关于TCP_NODELAY的文章。
/**
 * TCP_NO_DELAY option. JVM default used if not set.
 */
protected Boolean tcpNoDelay = Boolean.TRUE;