当两个socket处于连接的情况下,先用ctrl+c关掉的一方套接字会处于time_wait状态。如果是客户端先关闭,time_wait不会对下次重新启动有影响,因为client会随机分配一个端口。
而如果是服务器先关闭,这时服务器的端口就会处于time_wait状态,这时如果重启服务器程序,bind函数会失败。
解决方法是在bind之前开启上TCP REUSE选项,一般要将服务器程序写成下面这样:
注意 bind函数之前的两条语句!
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int main()
{
int sockfd, newsockfd;
socklen_t clilen ;
struct sockaddr_in cli_addr, serv_addr;
memset(&serv_addr , 0 , sizeof(serv_addr)) ;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8000);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
int on = 1;
setsockopt(sockfd , SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)) ;
int ret = bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if(ret < 0) {
perror("") ;
exit(1) ;
}
listen(sockfd, 5);
int recv_len ;
char recvbuf[8000] ;
for(;;) {
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
while(1){
recv_len = read(newsockfd, recvbuf, sizeof(recvbuf));
printf("recv : %d\n", recv_len);
}
close(newsockfd);
}
return 0;
}