2011-10-03 42 views
17

我有一个由主服务器和分布式从服务器组成的程序。从服务器向服务器发送状态更新,如果服务器在固定时间内没有收到特定的从服务器的响应,则会将从服务器标记为关闭。这一直在发生。无法分配请求的地址 - 可能的原因?

从检查日志,我发现从站只能发送一个状态更新到服务器,然后永远不能发送另一个更新,总是失败的通话连接()“无法分配请求的地址(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); 

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

+0

我已经验证了端口和ip地址都是正确的。 – dbeer

回答

9

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

+0

SO_REUSEADDR为所有连接设置。 – dbeer

+1

这里有一个类似的:http://stackoverflow.com/questions/3886506/why-would-connect-give-eaddrnotavail – dmh2000

+0

@ dmh2000 - 我在发布之前看过这个例子,并没有试图成功研究这些因素。我想知道如果我只是需要继续看,或者有什么我没有考虑到。 – dbeer

3

这仅仅是一个在黑暗中拍摄:当你调用连接而无需绑定第一,系统分配的本地端口,如果你有连接和断开它可能尝试已经分配一个端口多线程使用。内核源文件inet_connection_sock.c提示此情况。就像实验尝试先绑定本地端口一样,确保每个绑定/连接使用不同的本地端口号。

+0

我会试试看看它是否有帮助 – dbeer

+0

对不起,我发布时没有看到我的代码。我在连接之前调用绑定。我会更新我的问题以更好地展示我在做什么。 – dbeer

5

事实证明,问题确实是地址繁忙 - 繁忙是由于我们处理网络通信的一些其他问题导致的。你的投入帮助我弄清楚了这一点。谢谢。

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

+0

如果在我自己的代码中出现同样错误的原因,我会喜欢对“繁忙”进行阐述 - 您的意思是“服务器接受连接的套接字队列等待accept()以等待另一个连接被允许放在队列中?“或者是另一种情况?谢谢! –

+2

@BrandonRhodes我们的问题是,我们有一些重试发生没有​​适当的退避算法,所以我们每秒钟有数百个或更多的连接尝试到同一个套接字。这个争论导致了我们的失败。实施适当的退避算法对解决这个问题至关重要。 – dbeer

+0

感谢您的额外信息!很高兴你修好了它。 –

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

你如何撤销这2个? – ado

+6

没有解释这个答案没有任何价值。 –

相关问题