2011-04-03 67 views
0

我正在编写,运行,调试客户端连接到的FreeBSD上的TCP服务器。当服务器崩溃或有些不正常时,我经常遇到问题,因为我的bind()调用失败,导致服务器无法备份。当发生这种情况,当然我能找到的netstat -n如下:我的TCP代码中的FIN_WAIT_2阻止打开套接字

Active Internet connections 
Proto Recv-Q Send-Q Local Address   Foreign Address  (state) 
tcp4  0  0 192.168.2.xxx.12345 xx.yy.zz.ww.54201  FIN_WAIT_2 

这是相当刺激性的,因为我在这里坐一分钟或2或3,直到它清除出去。我已经尽了最大努力避免这种情况:

if((socketId = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) ... 

// Set socket to nonblocking. If this is < 0 there was a failure 
if(fcntl(socketId, F_SETFL, O_NONBLOCK) < 0) ... 


// Linger settings 
struct linger so_linger; 
so_linger.l_onoff = 1; // Turn linger option TRUE! 
so_linger.l_linger = 0; // And inform to DO NOT LINGER 


if(setsockopt(socketId, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger)) < 0) ... 

那么,为什么我收到了挥之不去的行为?这是在FreeBSD上,但在我移植我的代码之前,我在Linux上遇到了同样的问题。我试图将代码放在代码中,以便在“control-c”杀死我的服务器时,它应该在所有这些套接字上运行并立即退出。这似乎没有帮助

+1

尝试设置SO_REUSEADDR和SO_REUSEPORT - 如果其中任何一个可用于fbsd。 – Erik 2011-04-03 19:12:46

回答

2

尝试设置套接字选项SO_REUSEADDR

SO_REUSEADDR表示在验证bind(2)调用中提供的地址时使用的规则应允许重用本地地址。

AIUI中,O/S通常不会让你bind如果有一个插座留在该端口上游逛,而这个电话应该告诉O/S允许它。

+0

工程就像一个魅力。谢谢 – Nektarios 2011-04-03 19:24:30

0

你也可以看看相关的sysctl:

  • net.inet.tcp.fast_finwait2_recycle
  • net.inet.tcp.finwait2_timeout

设置循环= 1和超时下来到一个理智的东西(5k毫秒,你的里程可能会有所不同)对我的一个盒子有很大的帮助..

HTH :)

-jamie