我有Java代码在特定端口上设置服务器,某些代码在使用此服务器的python中运行,然后端口关闭。我已经设置好了,所以在每次python运行之后,java循环并重复这个过程(设置一个新的服务器,服务,然后关闭)。
我注意到当python调用很短(大约<10s)时,下次Java尝试设置此端口时,它将失败。关于在Java上连续设置相同端口之间必须等待多长时间的规则?
答案 0 :(得分:1)
对于这种类型的东西,端口可能很挑剔。他们并不打算一直打开和关闭。您应该打开套接字并只处理其中的每个连接,如下所示:
ServerSocket listener = new ServerSocket(9090);
try {
while (true) {
Socket socket = listener.accept();
try {
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
out.println(new Date().toString());
} finally {
socket.close();
}
}
}
finally {
listener.close();
}
答案 1 :(得分:1)
一般情况下,最好维护一个长期运行的ServerSocket
来处理多个请求,因为其他人已经回答并发表了评论。但是,我发现有时需要快速连续停止和启动服务器。一个示例是集成测试套件,其涉及以不同配置停止和重新启动服务器以重复测试运行。
如果您真的有此需求,那么您可能会对ServerSocket#setReuseAddress(boolean)
感兴趣。
启用/禁用SO_REUSEADDR套接字选项。 当TCP连接关闭时,连接可能在连接关闭后的一段时间内保持超时状态(通常称为TIME_WAIT状态或2MSL等待状态)。对于使用众所周知的套接字地址或端口的应用程序,如果在涉及套接字地址或端口的超时状态中存在连接,则可能无法将套接字绑定到所需的SocketAddress。
在使用bind(SocketAddress)绑定套接字之前启用SO_REUSEADDR允许套接字绑定,即使先前的连接处于超时状态。
这最终启用了SO_REUSEADDR
套接字选项。有关这些套接字选项的更多详细信息,请参阅Linux socket
手册页。
但是,请注意,不同平台上的确切感知行为可以非常大。特别是,请注意Windows上此设置的极端不同和危险行为,如MSDN文章Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE中所述。基本上,Windows上的SO_REUSEADDR
可以允许任意进程来“偷”&#34;另一个进程已经使用的套接字,导致不确定的行为。
SO_REUSEADDR套接字选项允许套接字强制绑定到另一个套接字使用的端口。第二个套接字调用setsockopt,其optname参数设置为SO_REUSEADDR,optval参数设置为布尔值TRUE,然后在与原始套接字相同的端口上调用bind。第二个套接字成功绑定后,绑定到该端口的所有套接字的行为都是不确定的。例如,如果同一端口上的所有套接字都提供TCP服务,则无法保证端口上的任何传入TCP连接请求都由正确的套接字处理 - 该行为是不确定的。恶意程序可以使用SO_REUSEADDR强制绑定已用于标准网络协议服务的套接字,以拒绝访问这些服务。使用此选项无需特殊权限。
我建议人们仔细思考并确保您对此设置充满信心,而不是盲目地打开它。关于相关套接字选项,还有一个非常先前的问题和答案: