简体   繁体   English

使用连接构造函数创建的套接字的连接超时是多少?

[英]What's the connection timeout of a socket created with a connecting constructor?

What's the connection timeout of a socket created with a connecting constructor? 使用连接构造函数创建的套接字的连接超时是多少?

In Java SE 6, the following constructors for Socket will connect the socket right away instead of you having to call connect on it after construction: 在Java SE 6中,Socket的以下构造函数将立即连接套接字,而不是在构造之后必须在其上调用connect:

  • Socket(InetAddress address, int port)
  • Socket(InetAddress host, int port, boolean stream)
  • Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
  • Socket(String host, int port)
  • Socket(String host, int port, boolean stream)
  • Socket(String host, int port, InetAddress localAddr, int localPort)

While it's nice and convenient and all that the Java SE folks created 500 ways of constructing a socket so you can just browse the list of 500 to find the one that sort of does what you want (instead of calling new Socket() followed by Socket#connect() ), none of the docs of these constructors says what the connection timeout is or whether/how they call connect(SocketAddress endpoint, int timeout) . 虽然它很方便,所有Java SE人员创建了500种构造套接字的方法,所以你只需要浏览500的列表就可以找到你想要的那种(而不是调用new Socket()后跟Socket#connect() ),这些构造函数的所有文档都没有说明连接超时是什么,或者它们是否/如何调用connect(SocketAddress endpoint, int timeout)

Perhaps the stuff in the constructor docs talking about createSocketImpl imply something about the timeout, or some docs somewhere else say it? 也许构造函数docs中关于createSocketImpl东西暗示了关于超时的东西,或者其他地方的一些文档说的呢?

Anyone know what the actual connection timeout for any of these constructors is? 任何人都知道这些构造函数的实际连接超时是什么?


Background: Okay, assuming the spec is really ambiguous (I thought Java is portable?), I'm trying to figure out why a customer's code freezes at seemingly random times. 背景:好的,假设规范真的很模糊(我认为Java是可移植的?),我试图弄清楚为什么客户的代码会在看似随机的时候冻结。 I have some code that calls some open source library which calls one of these constructors. 我有一些代码调用一些开源库来调用其中一个构造函数。 I want to know whether calling one of these constructors would have made the timeout infinite or very long. 我想知道调用其中一个构造函数是否会使超时无限或很长。 I don't know what version of the JDK the customer is using so it would be nice if the spec says the timeout somewhere. 我不知道客户使用的是什么版本的JDK,所以如果规范在某个地方说出超时,那就太好了。 I guess I can probably get the JDK version from my customer, but it will probably be the closed source JDK. 我想我可以从我的客户那里获得JDK版本,但它可能是闭源JDK。 In that case, could I reverse-engineer the code in their version of the SE library to find out? 在这种情况下,我可以对他们的SE库版本中的代码进行反向工程以找出答案吗? Is it hard? 难吗? Will I go to jail? 我会去监狱吗?

Even though Java docs says the timeout is infinite, it actually means that JVM will not impose any timeout on the connect operation, however OS is free to impose timeout settings on any socket operations. 尽管Java文档说超时是无限的,但它实际上意味着JVM不会对连接操作施加任何超时,但操作系统可以自由地对任何套接字操作施加超时设置。

Thus the actual timeout will be dependent on your OS's TCP/IP layer settings. 因此,实际超时将取决于操作系统的TCP / IP层设置。

A good programming practice is to set timeouts for all socket operations, preferably configurable via configuration file. 一个好的编程习惯是为所有套接字操作设置超时,最好通过配置文件进行配置。 The advantage of having it configurable is that depending on the network load of the deployment environment, the timeout can be tweaked without re-building/re-testing/re-releasing the whole software. 使其可配置的优点是,根据部署环境的网络负载,可以调整超时,而无需重新构建/重新测试/重新发布整个软件。

Java spec is bogus. Java规范是假的。 It doesn't say what timeout is on any of those constructor so implementation could set timeout to 0.000000000001 nanoseconds and still be correct. 它没有说明任何构造函数的超时是什么,因此实现可以将超时设置为0.000000000001纳秒并且仍然是正确的。 Furthurmore: non finite timeout not even respected by vm implementations (as seen here) so look like spec doesnt even matter cause noone followed it. 更多:vm实现甚至没有遵守非有限超时(如此处所示)所以看起来像spec甚至不重要因为没有人跟着它。

Conclusion: You have to read closed source binary of customer JVM (probably illegal but you have to do what you have to do), also OS socket doc. 结论:您必须阅读客户JVM的闭源二进制文件(可能是非法的,但您必须做您必须做的事情),也是OS套接字文档。

查看code of Socket in OpenJDK 6-b14 ,您可以看到这些构造函数调用connect(socketAddress, 0) ,这意味着无限超时值。

According to the sources (I'm looking at 1.5_13 here, but there shouldn't be a difference), the different Socket constructors all call Socket(SocketAddress, SocketAddress, boolean) which is defined as: 根据消息来源(我在这里看1.5_13,但应该没有区别),不同的Socket构造函数都调用Socket(SocketAddress, SocketAddress, boolean) ,定义如下:

private Socket(SocketAddress address, SocketAddress localAddr,
           boolean stream) throws IOException {
    setImpl();

    // backward compatibility
    if (address == null)
        throw new NullPointerException();

    try {
        createImpl(stream);
        if (localAddr == null)
        localAddr = new InetSocketAddress(0);
        bind(localAddr);
        if (address != null)
        connect(address);
    } catch (IOException e) {
        close();
        throw e;
    }
}

connect(SocketAddress) is defined as connect(SocketAddress)定义为

public void connect(SocketAddress endpoint) throws IOException {
    connect(endpoint, 0);
}

Hence, infinite timeout (as @Keppil already stated). 因此,无限超时(如@Keppil已经说明的那样)。

The Socket class exists since Java 1.0, but at that time, it was only possible to create sockets, which were immediately connected and it was not possible to specify a connect timeout. Socket类自Java 1.0以来就存在,但在那时,它只能创建立即连接的套接字,并且无法指定连接超时。 Since Java 1.4, it has been possible to create unconnected sockets and then specify a timeout using the connect method. 从Java 1.4开始,可以创建未连接的套接字,然后使用connect方法指定超时。 I assume that someone simply forgot to clarify the documentation of the "old" constructors, specifying that these still operate without an explicit timeout. 我假设有人只是忘了澄清“旧”构造函数的文档,指定它们仍然在没有显式超时的情况下运行。

The documentation of the connect methods with timeout parameter reads that "a timeout of zero is interpreted as an infinite timeout". 带有timeout参数的connect方法的文档读取“超时为零被解释为无限超时”。 This is actually incorrect as well, since it only means that no timeout is implied by the Java VM. 这实际上也是不正确的,因为它只意味着Java VM没有暗示超时。 Even with a timeout of 0, the connect operation may still timeout in the operating system's TCP/IP stack. 即使超时为0,连接操作仍可能在操作系统的TCP / IP堆栈中超时。

It's platform-dependent but it's around a minute. 它取决于平台,但大约需要一分钟。 The Javadoc for connect() is incorrect in stating that it is infinite. connect()的Javadoc声明它是无限的是不正确的。 Note also that the connect() timeout parameter can only be used to decrease the default, not increase it. 另请注意,connect()timeout参数只能用于降低默认值,而不能增加默认值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM