netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'查看, 基本都是CLOSE_WAIT状态的TCP连接. 出现CLOSE_WAIT状态的TCP连接, 根本原因是服务器被动断开TCP连接时, 没有执行close(socketfd)操作. 刚开始我希望通过关闭fd来解决问题, 但是由于服务器的代码实现很垃圾, 基本处于不可维护状态, 在异常处理(主要是检查recv()的返回值, 如果是0, 则表明peer断开连接了, 我们可以执行close操作)时, 也不能直接关闭fd, 因为其他地方可能还在使用这个socket.
最后, 决定使用keepalive来限制CLOSE_WAIT状态的TCP个数, 在创建socket时, 作以下设置:
点击(此处)折叠或打开
-
opt = 1;
-
opt_len = sizeof(opt);
-
ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &opt, opt_len);
-
if (ret < 0)
-
{
-
ERR("set SO_KEEPALIVE option failed\n");
-
return ;
-
}
-
opt = 5;
-
ret = setsockopt(sockfd, SOL_TCP, TCP_KEEPCNT, &opt, opt_len);
-
if (ret < 0)
-
{
-
ERR("set TCP_KEEPCNT option failed\n");
-
return ;
-
}
-
opt = 60;
-
ret = setsockopt(sockfd, SOL_TCP, TCP_KEEPIDLE, &opt, opt_len);
-
if (ret < 0)
-
{
-
ERR("set TCP_KEEPIDLE option failed\n");
-
return ;
-
}
-
opt = 10;
-
ret = setsockopt(sockfd, SOL_TCP, TCP_KEEPINTVL, &opt, opt_len);
-
if (ret < 0)
-
{
-
ERR("set TCP_KEEPINTVL option failed\n");
-
return ;
- }