免费网站建设模板下载,宁波seo网站,佛山高端网站制作公司,搜索引擎排名网站《TIME_WAIT相关知识》里边有相关理论知识。 《TIME_WAIT状态TCP连接导致套接字无法重用实验》有相关实验。
现代Linux的TCP协议栈已经做了许多升级#xff0c;所以可以让我们直接重用TIME_WAIT状态套接字而不会引起问题。下边是优化的内容#xff1a; 1.新连接的SYN告知序列…《TIME_WAIT相关知识》里边有相关理论知识。 《TIME_WAIT状态TCP连接导致套接字无法重用实验》有相关实验。
现代Linux的TCP协议栈已经做了许多升级所以可以让我们直接重用TIME_WAIT状态套接字而不会引起问题。下边是优化的内容 1.新连接的SYN告知序列号比原来TIME_WAIT老连接末序列号要大所以就可以通过序列号分辨出来新老连接。 2.开启tcp_timestamps这样就让新连接时间戳比旧连接时间戳大这样可以通过检查时间戳来判断新老连接。 在这样两重优化下重用TIME_WAIT状态连接就不会产生任何问题了。
int on 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, on, sizeof(on));SO_REUSEADDR用来告诉操作系统内核如果端口已被占用但是 TCP 连接状态位于 TIME_WAIT 可以重用端口。这段代码需要放到socket函数和bind函数之间。 下边是timeWaitSetsockopt.c完整代码
#includestdio.h
#includestdlib.h
#includestring.h
#includeunistd.h
#includearpa/inet.h
#includesys/socket.h
#includeerrno.h
#includesyslog.h
#includesignal.hvoid error_handling(char *buf);#define MAXLINE 1024
static int count;
static void sig_int(int signo) {printf(\nreceived %d datagrams\n, count);exit(0);
}
int main(int argc, char **argv) {if (argc ! 2) {error_handling(usage: select01 IPaddress or Port);}int serv_sock socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in server_addr;memset(server_addr, 0, sizeof(server_addr));server_addr.sin_familyAF_INET;server_addr.sin_addr.s_addrhtonl(INADDR_ANY);server_addr.sin_porthtons(atoi(argv[1]));// SO_REUSEADDR用来告诉操作系统内核如果端口已被占用但是 TCP 连接状态位于 TIME_WAIT 可以重用端口int on 1;setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, on, sizeof(on));if(bind(serv_sock, (struct sockaddr*) server_addr, sizeof(server_addr))-1){fprintf(stderr, error in bind: %s (%d)\n, strerror(errno), errno);exit(errno);}if(listen(serv_sock, 5)-1){fprintf(stderr, error in listen: %s (%d)\n, strerror(errno), errno);exit(errno);}signal(SIGPIPE, sig_int);int connfd;struct sockaddr_in client_addr;socklen_t client_len sizeof(client_addr);if ((connfd accept(serv_sock, (struct sockaddr *) client_addr, client_len)) 0) {printf(accept failed);exit(0);}char message[MAXLINE];count 0;int n;for (;;) {int n read(connfd, message, MAXLINE);if (n 0) {fprintf(stderr, error in read: %s (%d)\n, strerror(errno), errno);exit(0);} else if (n 0) {fprintf(stderr, client closed: %s (%d)\n, strerror(0), 0);exit(0);}message[n] 0;printf(received %d bytes: %s\n, n, message);count;}
}
void error_handling(char *buf)
{fputs(buf, stderr);fputc(\n, stderr);exit(1);
}在服务器端sudo gcc timeWaitSetsockopt.c -o timeWaitSetsockopt进行编译sudo ./timeWaitSetsockopt 8080启动程序。
在客户端使用sudo telnet 127.0.0.1 8080进行连接然后输入good之后按下回车键。
然后在服务器端同时按住ctrlc关闭程序之后快速再使用sudo ./timeWaitSetsockopt 8080启动程序然后快速在客户端使用sudo telnet 127.0.0.1 8080进行连接输入network之后按下回车键还是需要在服务器端快速按下sudo netstat -altnp | grep 8080看一下连接状态这些动作只要够快就可以出现两条记录。