开发者

FIN_WAIT_2 from my TCP code prevents opening socket

I'm writing, running, debugging a TCP server on FreeBSD that my clients connect to. When the server crashes or comes down somewhat ungracefully, often I have issues where I can't bring the server back up because my bind() call fails. When this happens of course I can find the following in 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开发者_如何学JAVA.ww.54201      FIN_WAIT_2

This is pretty irritating as I sit here for a minute or 2 or 3 until it clears out. I have tried my best to avoid this:

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

So, why am I getting the lingering behavior? This is on FreeBSD but I had the same issue on Linux before I ported my code here. I have tried to put in code so that when I "control-c" kill my server it should run a close on all these sockets and immediately exit. That did not seem to help


Try setting the socket option SO_REUSEADDR.

SO_REUSEADDR indicates that the rules used in validating addresses supplied in a bind(2) call should allow reuse of local addresses.

AIUI, the O/S won't usually allow you to bind if there's a socket left hanging around on that port, and this call should tell the O/S to permit it.


You could also take a look at sysctls:

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

setting recycle=1 and the timeout down to something sane (5k ms, your mileage may vary) helped quite a bit on one of my boxes..

HTH :)

-jamie

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜