套接字绑定错误 [英] Socket Bind Error

查看:100
本文介绍了套接字绑定错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个测试应用程序打开一个套接字,通过这个套接字发送一些东西,然后关闭它。这循环完成5-10.000次。问题是在3,4000次迭代后我得到了这种类型的错误:

I have a test application that opens a socket , sends something through this socket and then closes it . This is done in a loop for 5-10.000 times. The thing is that after 3,4000 iterations I get an error of this type :

java.net.BindException: Address already in use: connect

我甚至设置套接字即时使用,但错误仍然存​​在

I even set the socket to be used immediattly, but the error persists

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");
}

我该怎么做才能解决这个问题?

What could I do to fix this ?

推荐答案

我想你可能会走得太快。

I think you may be going too fast.

大多数操作系统对任何时候都可以打开的套接字数量有限制,但实际上比这更糟。

Most operating systems have a limit on the number of sockets they can have open at any one time but it's actually worse than that.

当套接字关闭时,它被放置在特定的时间等待状态下持续一段时间。这通常是数据包生存时间值的两倍,它可以确保网络中没有仍在发送到套接字的数据包。

When a socket is closed down, it is put in a special time-wait state for a certain amount of time. This is usually twice the packet time-to-live value and it ensures that there aren't still packets out in the network that are on the way to your socket.

一旦该时间到期,您可以确保网络中的所有数据包都已经死亡。套接字处于特殊状态,这样当你关闭它时,网络中出来的数据包如果在它们死亡之前到达就可以被捕获并扔掉。

Once that time expires, you can be sure that all packets out in the network have already died. The socket is placed in that special state so that packets that were out in the network when you shut it down can be captured and thrown away if they arrive before they die.

我认为这就是你的情况下发生的事情,套接字并没有像你想象的那样快速释放。

I think that's what's happening in your case, the sockets aren't being freed as quickly as you think.

我们遇到类似的问题,代码开了很多短 - 生活会议。它运行良好一段时间,但随后硬件变得更快,允许在给定的时间段内打开更多。这表明自己无法开设更多会议。

We had a similar problem with code that opened lots of short-lived sessions. It ran fine for a while but then the hardware got faster, allowing many more to be opened in a given time period. This manifested itself as inability to open more sessions.

检查这一点的一种方法是从 netstat -a 命令行,看看有多少会话实际上处于等待状态。

One way to check this is to do netstat -a from the command line and see how many sessions are actually in the wait state.

如果情况确实如此,有几种方法可以处理它。

If that does turn out to be the case, there's a few ways to handle it.


  • 手动或通过维护连接池重新使用会话。

  • 引入延迟尝试停止达到饱和点的每个连接。

  • 直到达到饱和状态并然后修改您的行为,例如在内部运行连接逻辑同时声明重复最多60次,每次延迟两秒,然后完全放弃。这可以让你全速运行,只有在出现问题时才会减速。

  • re-use your sessions, either manually or by maintaining a connection pool.
  • introduce a delay in each connection to try and stop reaching the saturation point.
  • go flat out until you reach saturation and then modify your behaviour, such as running your connect logic inside a while statement that retries for up to 60 times with a two-second delay each time before giving up totally. This lets you run at full speed, slowing down only if there's a problem.

最后一个要点值得一些扩展。我们实际上在前面提到的应用程序中使用了退避策略,如果它抱怨的话,它会逐渐减轻资源提供者的负担,而不是30秒延迟,我们选择了一秒钟的延迟,然后是两秒钟,然后四个等等。

That last bullet point deserves some expansion. We actually used a back-off strategy in our afore-mentioned application which would gradually lessen the load on a resource provider if it was complaining so, instead of 30 two-second delays, we opted for a one-second delay, then two seconds, then four and so on.

退避策略的一般过程如下,它可用于任何可能暂时短缺的情况资源。在下面的伪代码中提到的操作将是在您的情况下打开套接字。

The general process for a back-off strategy is as follows and it can be used in any case where there may be temporary shortages of a resource. The action alluded to in the pseudo-code below would be the opening of a socket in your case.

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

这允许进程在绝大多数情况下全速运行,但在错误开始发生时退出,希望给资源提供者时间版本。延迟的逐渐增加允许更严格的资源限制来恢复,并且最大尝试会捕获您所谓的永久性错误(或者需要花费很长时间才能恢复的错误)。

This allows the process to run at full speed in the vast majority of cases but backs off when errors start occurring, hopefully giving the resource provider time to recover. The gradual increase in delays allows for more serious resource restrictions to recover and the maximum tries catches what you would term permanent errors (or errors that are taking too long to recover).

这篇关于套接字绑定错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆