我想你可能会太快。
大多数操作系统在任何时候都可以打开的套接字数量有限制,但实际上这比其更糟。
当套接字关闭时,它会处于特定的时间等待状态一段时间。这通常是数据包生存时间值的两倍,并且可以确保网络中没有数据包正在通往套接字的路径中。
一旦该时间到期,您可以确定网络中的所有数据包已经死亡。套接字被置于特殊状态,以便在关闭网络时在网络中传出的数据包可以在它们死亡之前到达时被捕获并丢弃。
我认为这就是你的情况,套接字没有像你想象的那样被快速释放。
我们有一个类似的代码打开了很多短暂的会话问题。它运行良好一段时间,但随后硬件变得更快,允许在给定的时间段内打开更多的硬件。这表现为无法开放更多会议。
检查此的一种方法是从命令行执行netstat -a
并查看有多少会话实际处于等待状态。
如果情况确实如此,有几种方法可以处理它。
- 重新使用您的会话,无论是手动或通过维护连接池。
- 在每个连接中引入延迟尝试并停止达到饱和点。
- 直到你达到饱和,然后然后修改你的行为,比如在一个while语句内运行你的连接逻辑,每次在完全放弃之前每次重试最多60次,延迟时间为2秒。这可以让您全速运行,只有在出现问题时才会放慢速度。
这最后的子弹一点值得一些扩展。实际上,我们在上述应用中使用了一种退避策略,如果它在抱怨,那么它将逐渐减少资源提供者的负载,而不是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
这使得处理能够以全速在绝大多数情况下运行,但回退时的错误开始发生,希望给资源提供者的时间来恢复。延迟的逐渐增加允许更严重的资源限制来恢复,并且最大的尝试可以捕捉到您所称的永久性错误(或需要很长时间才能恢复的错误)。
你必须配置插座TIME_WAIT等相关paramters根据不同的操作系统(机器要连接到) – 2009-07-06 06:37:50
它并不总是一个好主意,用这些参数拨弄。大多数应该针对网络特性进行调整,然后您的应用程序应该进行调整。在不减少生存时间的情况下减少time_wait将导致虚假数据包到达。将TTL减少到数据包无法到达目的地意味着大量丢弃的数据包。理想情况下,您应该保持连接处于打开状态(手动或连接池)或调整应用程序行为(例如在他的回答中提及@Stu提及的延迟)。 – paxdiablo 2009-07-06 06:40:44