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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7640619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:48:17  来源:igfitidea点击:

Cannot assign requested address - possible causes?

csocketstcperrno

提问by dbeer

I have a program that consists of a master server and distributed slave servers. The slave servers send status updates to the server, and if the server hasn't heard from a specific slave in a fixed period, it marks the slave as down. This is happening consistently.

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

From inspecting logs, I have found that the slave is only able to send one status update to the server, and then is never able to send another update, always failing on the call to connect() "Cannot assign requested address (99).

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

Oddly enough, the slave is able to send several other updates to the server, and all of the connections are happening on the same port. It seems that the most common cause of this failure is that connections are left open, but I'm having trouble finding anything left open. Are there other possible explanations?

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

To clarify, here's how I'm connecting:

为了澄清,这是我的连接方式:

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

This code is in a function to obtain a connection to another server, and a failure on any of those 4 calls causes the function to fail.

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

采纳答案by Michel

Maybe SO_REUSEADDR helps here? http://www.unixguide.net/network/socketfaq/4.5.shtml

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

回答by dbeer

It turns out that the problem really was that the address was busy - the busyness was caused by some other problems in how we are handling network communications. Your inputs have helped me figure this out. Thank you.

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

EDIT:to be specific, the problems in handling our network communications were that these status updates would be constantly re-sent if the first failed. It was only a matter of time until we had every distributed slave trying to send its status update at the same time, which was over-saturating our network.

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

回答by dmh2000

this is just a shot in the dark : when you call connect without a bind first, the system allocates your local port, and if you have multiple threads connecting and disconnecting it could possibly try to allocate a port already in use. the kernel source file inet_connection_sock.c hints at this condition. just as an experiment try doing a bind to a local port first, making sure each bind/connect uses a different local port number.

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

回答by Soli

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