29

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

通过检查日志,我发现从站只能向服务器发送一个状态更新,然后永远无法发送另一个更新,总是在调用 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 个调用中的任何一个失败都会导致该函数失败。

4

5 回答 5

15

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

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

于 2011-10-04T21:56:38.260 回答
11

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

于 2011-10-03T21:08:45.443 回答
6

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

于 2011-10-03T22:56:00.510 回答
3

好吧,我的问题不是端口,而是绑定地址。我的服务器有一个内部地址 (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

于 2020-12-15T10:11:12.600 回答
-12
sysctl -w net.ipv4.tcp_timestamps=1
sysctl -w net.ipv4.tcp_tw_recycle=1
于 2012-11-12T01:20:55.293 回答