原因分析:
socket关闭之后并不会立即收回,而是要经历一个TIME_WAIT的阶段。windows下最多可以达到4分钟。在这个时候对这个端口进行重新绑定就会出错。
time_wait状态是一般有客户端的状态。而且会占用端口。有时产生在服务器端,因为服务器主动断开连接或者发生异常。
方式一:
设置 SO_REUSEADDR
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) return -1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) { close(fd); return -1; }
方式二:
在closesocket的时候,使用setsockopt设置SO_DONTLINGER。
int z; /* Status code*/ int s; /* Socket s */ struct linger so_linger; ... so_linger.l_onoff = TRUE; so_linger.l_linger = 30; // 30秒的超时时限 z = setsockopt(s, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger); if ( z ) perror("setsockopt(2)");
这l两种方式可以跳过TIME_WAIT的阶段,客户端重启后可以快速进行连接。通常使用这个设置来加强网络程序的健壮性。