无法分配请求的地址 - 可能的原因?

时间:2011-10-03 21:03:32

标签: c sockets tcp errno

我有一个由主服务器和分布式从服务器组成的程序。从属服务器向服务器发送状态更新,如果服务器在固定时间内没有从特定从属设备收到消息,则它将从属设备标记为关闭。这种情况一直在发生。

从检查日志开始,我发现从服务器只能向服务器发送一个状态更新,然后永远无法发送另一个更新,总是无法调用connect()“无法分配请求的地址( 99)。

奇怪的是,从服务器能够向服务器发送多个其他更新,并且所有连接都发生在同一端口上。似乎这种失败的最常见原因是连接处于打开状态,但我无法找到任何未解决的问题。还有其他可能的解释吗?

澄清一下,这就是我的联系方式:

struct sockaddr *sa; // parameter
size_t           sa_size; //parameter
int              i = 1;
int              stream;

stream = socket(AF_INET,SOCK_STREAM,0);
setsockopt(stream,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
bindresvport(stream,NULL);
connect(stream,sa,sa_size);

此代码用于获取与另一台服务器的连接,并且这4次调用中的任何一次失败都会导致该函数失败。

5 个答案:

答案 0 :(得分:9)

也许SO_REUSEADDR在这里有帮助? http://www.unixguide.net/network/socketfaq/4.5.shtml

答案 1 :(得分:6)

事实证明,问题实际上是地址繁忙 - 忙碌是由我们处理网络通信的其他一些问题引起的。你的意见帮我解决了这个问题。谢谢。

编辑:具体而言,处理我们的网络通信的问题是,如果第一次失败,这些状态更新将不断重新发送。我们让每个分布式从站试图同时发送其状态更新只是时间问题,这使我们的网络过度饱和。

答案 2 :(得分:4)

这只是一个黑暗的镜头:当你首先调用connect而没有绑定时,系统会分配你的本地端口,如果有多个线程连接和断开连接,它可能会尝试分配一个已经在使用的端口。内核源文件inet_connection_sock.c暗示了这种情况。就像一个实验尝试首先绑定到本地端口,确保每个绑定/连接使用不同的本地端口号。

答案 3 :(得分:0)

好的,我的问题不是端口,而是绑定地址。我的服务器有一个内部地址(10.0.0.4)和一个外部地址(52.175.223.XX)。当我尝试连接时:

$sock = @stream_socket_server('tcp://52.175.223.XX:123', $errNo, $errStr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN);

失败,因为本地套接字是10.0.0.4,而不是外部52.175.223.XX。您可以使用sudo ifconfig签出本地可用接口。

答案 4 :(得分:-6)

sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_recycle=1