理论相关知识可以看一下《TIME_WAIT相关知识》。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<errno.h>
#include<syslog.h>
#include<signal.h>void 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_family=AF_INET;server_addr.sin_addr.s_addr=htonl(INADDR_ANY);server_addr.sin_port=htons(atoi(argv[1]));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);
}
实验一
gcc timeWaitTest.c -o timeWaitTest
进行编译,./timeWaitTest 8080
执行,这是在服务器这样操作,然后在客户端使用sudo telnet 127.0.0.1 8080
进行连接,然后按照下图操作,进行第一步实验。
1.在客户端先输入network
,然后看到服务器端输出received 9 bytes: network
。
2.客户端同时按住ctrl+c,然后按下回车键,出现了telnet>
之后再输入quit
,然后服务器端出现了client closed: Success (0)
。
3.在服务器端快速输入./timeWaitTest 8080
,可以正常重启。
实验二
服务器./timeWaitTest 8080
运行,然后在客户端使用sudo telnet 127.0.0.1 8080
进行连接。
1.在客户端先输入network
,然后看到服务器端输出received 9 bytes: network
。
2.服务器端同时按住ctrl+c,可以看到客户端被动关闭了。
3.在服务器端快速输入./timeWaitTest 8080
,无法正常重启,输出error in bind: Address already in use (98)
。
在服务器端sudo netstat -altnp | grep 8080
查看一下8080
端口,发现这个端口还在监听,状态是TIME_WAIT
。当sudo netstat -altnp | grep 8080
看到没有任何数据输出的时候,就可以./timeWaitTest 8080
再次成功重启了。
此文章为11月Day 25学习笔记,内容来源于极客时间《网络编程实战》。