理论相关知识可以看一下《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学习笔记,内容来源于极客时间《网络编程实战》。