使用连接构造函数创建的套接字的连接超时是什么?
在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)
尽管它很方便,所有Java SE人员都创建了500种构建套接字的方法,因此您只需浏览500列表即可找到您想要的那种(而不是调用{{1} }后跟new Socket()
),这些构造函数的所有文档都没有说明连接超时是什么,或者是否/如何调用Socket#connect()
。
也许构造函数文档中讨论connect(SocketAddress endpoint, int timeout)
的内容暗示了超时的某些内容,或者其他地方的某些文档说的是什么?
任何人都知道这些构造函数的实际连接超时是什么?
背景:好的,假设规范真的很模糊(我认为Java是可移植的?),我试图弄清楚为什么客户的代码会在看似随机的时候冻结。我有一些代码调用一些开源库来调用其中一个构造函数。我想知道调用其中一个构造函数是否会使超时无限或很长。我不知道客户使用的是什么版本的JDK,所以如果规范在某个地方说出超时,那就太好了。我想我可以从我的客户那里获得JDK版本,但它可能是闭源JDK。在这种情况下,我可以对他们的SE库版本中的代码进行反向工程以找出答案吗?难吗?我会去监狱吗?
答案 0 :(得分:3)
尽管Java文档说超时是无限的,但它实际上意味着JVM不会对连接操作施加任何超时,但操作系统可以自由地对任何套接字操作施加超时设置。
因此实际超时将取决于操作系统的TCP / IP层设置。
一个好的编程习惯是为所有套接字操作设置超时,最好通过配置文件进行配置。使其可配置的优势在于,根据部署环境的网络负载,可以调整超时,而无需重新构建/重新测试/重新发布整个软件。
答案 1 :(得分:3)
Java规范是假的。它没有说明任何构造函数的超时是什么,因此实现可以将超时设置为0.000000000001纳秒并且仍然是正确的。 Furthurmore:非有限超时甚至不受vm实现的尊重(如此处所示)所以看起来像spec甚至不重要因为没有人跟着它。
结论:你必须阅读客户JVM的闭源二进制文件(可能是非法的,但你必须做你必须做的事情),也是OS套接字文档。
答案 2 :(得分:2)
查看code of Socket in OpenJDK 6-b14
,您可以看到这些构造函数调用connect(socketAddress, 0)
,这意味着无限超时值。
答案 3 :(得分:2)
根据消息来源(我在这里看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)
定义为
public void connect(SocketAddress endpoint) throws IOException {
connect(endpoint, 0);
}
因此,无限超时(正如@Keppil已经说过的那样)。
答案 4 :(得分:1)
Socket类自Java 1.0以来就存在,但那时,只能创建立即连接的套接字,并且无法指定连接超时。从Java 1.4开始,可以创建未连接的套接字,然后使用connect方法指定超时。我假设有人只是忘了澄清“旧”构造函数的文档,指定它们仍然在没有显式超时的情况下运行。
带有timeout参数的connect方法的文档读取“超时为零被解释为无限超时”。这实际上也是不正确的,因为它只意味着Java VM没有暗示超时。即使超时为0,连接操作仍可能在操作系统的TCP / IP堆栈中超时。
答案 5 :(得分:1)
它依赖于平台但是大约一分钟。 connect()的Javadoc声明它是无限的是不正确的。另请注意,connect()timeout参数只能用于降低默认值,而不能增加默认值。