我有一个测试应用程序打开一个套接字,通过这个套接字发送一些东西然后关闭它.这循环完成5-10.000次.事情是,在3,4000次迭代后,我得到了这种类型的错误:
java.net.BindException: Address already in use: connect
Run Code Online (Sandbox Code Playgroud)
我甚至设置了即时使用的套接字,但错误仍然存在
try
{
out_server.write(m.ToByteArray());
socket_server.setReuseAddress(true);
socket_server.close();
}
catch(Exception e)
{
e.printStackTrace();
System.out.println(i+" unable to register with the server");
}
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能解决这个问题?
pax*_*blo 11
我想你可能走得太快了.
大多数操作系统都限制了它们在任何时候都可以打开的插槽数量,但它实际上比这更糟糕.
当套接字关闭时,它将处于特定的时间等待状态一段时间.这通常是数据包生存时间值的两倍,它可以确保网络中没有仍然存在的数据包正在通往套接字的路上.
一旦该时间到期,您可以确保网络中的所有数据包都已经死亡.套接字处于特殊状态,以便在关闭时将网络中的数据包丢弃,如果它们在死亡之前到达,则可以将其丢弃.
我认为这就是你的情况,插座并没有像你想象的那样快速释放.
我们遇到了类似的问题,代码打开了很多短暂的会话.它运行良好一段时间,但随后硬件变得更快,允许在给定的时间段内打开更多.这表明自己无法开设更多会议.
检查此问题的一种方法是netstat -a从命令行执行操作,查看实际处于等待状态的会话数.
如果情况确实如此,那么有几种方法可以处理它.
最后一个要点值得一些扩展.我们实际上在前面提到的应用程序中使用了退避策略,如果它抱怨的话,它将逐渐减轻资源提供者的负担,而不是30秒的两秒延迟,我们选择了一秒钟的延迟,然后是两秒钟,然后是四个等等.
退避策略的一般过程如下,它可以在任何可能暂时缺乏资源的情况下使用.下面的伪代码中提到的操作将是在您的情况下打开套接字.
set maxdelay to 16 # maximum time period between attempts
set maxtries to 10 # maximum attempts
set delay to 0
set tries to 0
while more actions needed:
if delay is not 0:
sleep delay
attempt action
if action failed:
add 1 to tries
if tries is greater than maxtries:
exit with permanent error
if delay is 0:
set delay to 1
else:
double delay
if delay is greater than maxdelay:
set delay to maxdelay
else:
set delay to 0
set tries to 0
Run Code Online (Sandbox Code Playgroud)
这允许进程在绝大多数情况下以全速运行,但在错误开始时退出,希望为资源提供者提供恢复时间.延迟的逐渐增加允许更严格的资源限制来恢复,并且最大的尝试捕获您所谓的永久性错误(或者需要花费太长时间才能恢复的错误).
| 归档时间: |
|
| 查看次数: |
14836 次 |
| 最近记录: |