2013-02-08 44 views
2

我正在使用Socket类进行java TCP连接。使用超时连接Socket.connect

Socket socket = new Socket(); 
socket.connect(new InetSocketAddress(host,port),50); 

我想这个连接建立得很快或根本没有建立,所以我使用了50毫秒的连接超时时间。

但是,如果我测量这些调用之间的时间,我会得到超过50毫秒:125毫秒,甚至200毫秒。测量我使用System.currentMillis()的时间。我知道这种方法的粒度不是很好,但+ 100ms的差异只是荒谬的。

连接方法有问题吗?超时时间太短了50毫秒?我在Windows 7上使用java 1.7.0_03。

+0

我不知道这是没有实现的详细知识交代。底层操作系统也可能使用特定的最小值或粒度作为超时值。还要考虑从主机名解析IP地址所需的时间;这不是连接超时AFAIK的一部分。 – 2013-02-08 16:59:38

+2

您是在测量连接成功还是失败? – 2013-02-08 17:00:51

+0

也可能只有第一次连接尝试需要很长时间。尝试在100个连接的循环中测量它。 – 2013-02-08 17:03:07

回答

0

在tdn120的answer上展开我最后搬了println。我始终如一地使用< 100.我也运行Windows 7,Java 7(1.7.0)。

javac -g SocketTest.java && java SocketTest localhost:80 abcd.com:80 localhost:80 localhost:80 localhost:80 
Testing: localhost:80 
java.net.SocketTimeoutException: connect timed out 
Time: 63 
Testing: abcd.com:80 
java.net.UnknownHostException: abcd.com 
Time: 2350 
Testing: localhost:80 
java.net.SocketTimeoutException: connect timed out 
Time: 50 
Testing: localhost:80 
java.net.SocketTimeoutException: connect timed out 
Time: 50 
Testing: localhost:80 
java.net.SocketTimeoutException: connect timed out 
Time: 50 

我的代码如下:

import java.net.*; 

public class SocketTest { 
    public static void main(String[] args) throws Exception { 
     if (args.length == 0) { 
      args = new String[]{"localhost:80"}; 
     } 
     for (String target: args) { 
      test(target); 
     } 
    } 

    private static void test(String target) throws Exception { 
     System.out.println("Testing: " + target); 
     String[] parts = target.split(":"); 
     String host = parts[0]; 
     int port = Integer.valueOf(parts[1]); 
     Socket socket = new Socket(); 
     long start = 0; 
     try { 
      start = System.nanoTime(); 
      socket.connect(new InetSocketAddress(host, port), 50); 
     } catch (Exception e) { 
      System.out.println(e.toString()); 
     } finally { 
      long end = System.nanoTime(); 
      System.out.println("Time: " + ((end - start)/1000000)); 
     } 
    } 
} 
+0

是的,但这是我没有得到的。在你的例子中,你得到了63和2350.为什么?我的意思是你说的方法你不想等待超过50毫秒,所以为什么需要更长的时间。高达2350!也许你传递给连接方法的超时只是一种建议... – 2013-02-09 00:55:04

+0

我希望你会注意到额外的时间。 50毫秒是套接字连接超时。当我使用名称而不是i/p时,尤其是无效名称(abcd.com)时,dns失败需要更多时间。 – 2013-02-09 01:00:37

+0

在完成socket.close()操作后,我正在测量finally子句中的总时间。它似乎需要很多时间:( – 2013-02-10 19:42:17

0

我有一种感觉,它与你如何计时有关。您需要确保您在执行之前和之后立即记录时间。

虽然我使用Linux,我一直得到的51或52,此代码的结果:

public class SocketTest { 
    public static void main(final String[] args) throws IOException { 
     Socket socket = new Socket(); 
     long start = 0; 
     try { 
      start = System.nanoTime(); 
      socket.connect(new InetSocketAddress("192.168.1.100", 80), 50); 
     } catch (SocketTimeoutException e) { 
      long end = System.nanoTime(); 
      System.out.println("Time: " + ((end - start)/1000000)); 
     } 
    } 
} 

更新:我试了一下在Windows 7中,我得到50的和51的。

+0

我完全按照您的测量时间(但使用currentMillis而不是nanoTime)。实际上,当我使用我的专用网络中的主机时,我得到了50和51,但当我使用外部ips时却没有。 – 2013-02-09 00:48:34