我的TCP代码中的FIN_WAIT_2阻止打开套接字

时间:2011-04-03 19:09:21

标签: networking tcp freebsd sockets

我正在编写,运行,调试我的客户端连接到的FreeBSD上的TCP服务器。当服务器崩溃或有点不合适时,我常常遇到无法重新启动服务器的问题,因为我的bind()调用失败了。当发生这种情况时,我可以在netstat -n中找到以下内容:

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

这是非常恼人的,因为我坐在这里一两分钟或三分钟,直到它清除。我尽力避免这种情况:

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”杀死我的服务器时,它应该在所有这些套接字上运行关闭并立即退出。这似乎没有帮助

2 个答案:

答案 0 :(得分:2)

尝试设置套接字选项SO_REUSEADDR

  

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

AIUI,如果该端口上有一个套接字,O / S通常不会允许你bind,这个调用应告诉O / S允许它。

答案 1 :(得分:0)

您还可以查看一下sysctls:

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

设置recycle = 1并将超时降低到理智(5k ms,你的里程可能会有所不同)对我的一个盒子有很大的帮助..

HTH:)

-jamie