Linux网络编程 四次分手
/** * a sample server */ #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <string.h> #define PORT 8888 #define BACKLOG 2 void process_conn_server(int sock); int main(int argc, char **argv) { int sSock, cSock; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int err; pid_t pid; sSock = socket(AF_INET, SOCK_STREAM, 0); //创建一个TCP套接字 if(-1 == sSock) { printf("Create socket error"); return -1; } bzero(&server_addr, sizeof(server_addr)); //初始化地址空间 server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(PORT); err = bind(sSock, (struct sockaddr*)&server_addr, sizeof(server_addr)); if(err < 0) { printf("bind error"); return -1; } printf("Bind program is right,it return %dn",err); err = listen(sSock, BACKLOG); if(err < 0) { printf("listen error"); return -1; } printf("Listen program is right,it return %dn",err); for( ; ; ) { // int addrlen = sizeof(struct sockaddr); socklen_t addrlen = sizeof(struct sockaddr); cSock = accept(sSock, (struct sockaddr*)&client_addr, &addrlen); perror("The state is:"); pid = fork(); if(pid < 0) { printf("can't create new pid"); return -1; } if(pid == 0) { close(sSock); process_conn_server(cSock); exit(0); } else close(cSock); } // return 0; } void process_conn_server(int sock) { ssize_t size = 0; char buffer[1024]; char sendbuffer[25] = "Welcome to this servern"; write(sock, sendbuffer, 25 ); for( ; ; ) { size = read(sock, buffer, 1024); //当读到的字节位0,即发送方停止发送,就会返回 if(size == 0) return; // sprintf(buffer, "%d bytes altogethern", (int)size); write(sock, buffer, strlen(buffer) +1 ); write(STDOUT_FILENO, buffer, strlen(buffer) +1 ); } } /* * client.c * a sample client for server */ #include <arpa/inet.h> //#include <stdio.h> #include <stdlib.h> #include <string.h> //#include <sys/types.h> //#include <sys/socket.h> #include <unistd.h> #include <stdio.h> #include <netinet/in.h> #define PORT 8888 void process_conn_client(int s); int main(int argc, char *argv[]) { int s; if(argc != 2 ) { printf("client <Ipaddrs>n"); return -1; } struct sockaddr_in server_addr; s = socket(AF_INET, SOCK_STREAM, 0); if(s < 0) { printf("failed to creating socket"); return -1; } bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); inet_pton(AF_INET, argv[1], &server_addr.sin_addr); int cnum = connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)); //成功则返回0,否则为-1 if(cnum < 0) { printf("can't find the serversn"); return 0; } process_conn_client(s); exit(0); } void process_conn_client(int s) { ssize_t size = 0; char buffer[1024]; char recvbuffer[25]; read(s, recvbuffer, 25 ); write(STDOUT_FILENO, recvbuffer, strlen(recvbuffer) +1 ); for( ; ; ) { //buffer[1024] = {''}; size = read(0, buffer, 1024); //将标准输入读到buffer中,此处,要有个初始化 if(size > 0) write(s, buffer, strlen(buffer) +1 ); // printf(buffer); write(STDOUT_FILENO, buffer, strlen(buffer) +1 ); } }
服务端和客户端代码如上所示,当两者建立连接后,客户端断开,本来应该是4次分手的,但是我用wireshark抓包,却只抓到三个,向大家求解啊!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
@
Lunar_Lin:查阅了一下TCP/IP,确实有3次的和4次的,不是很明白为什么有3次和4次的区别,在这个代码中,要是加上一个信号处理函数,也就是让服务器主进程等待处理的子进程,就能够抓到4个包?
@
Lunar_Lin:查阅了一下TCP/IP,确实有3次的和4次的,不是很明白为什么有3次和4次的区别,在这个代码中,要是加上一个信号处理函数,也就是让服务器主进程等待处理的子进程,就能够抓到4个包?
4次分手我都没见过多少人遵守这个规则的,大家都认为反正最后超时就断开了,所以这就省了1分
查阅了一下TCP/IP,确实有3次的和4次的,不是很明白为什么有3次和4次的区别,在这个代码中,要是加上一个信号处理函数,也就是让服务器主进程等待处理的子进程,就能够抓到4个包?
有可能3次 有可能4次. 就看在对方停止接收后是否立即断开本地接收.
Afin ,Back, Bfin, Aack 或者 Afin, Bfin ack, Aack
参考 Tcp/ip详解
TCP不是三次分手吗?fin -> fin ack -> fin ack byebye?