shutdown函数和FIN_WAIT2状态
来源:互联网 发布:淘宝宝贝详情如何添加 编辑:程序博客网 时间:2024/06/13 17:29
玩过英雄联盟的人都不会对shutdown感到陌生,就是你连杀被终结了嘛。在网络编程中也差不多是这个意思,准确来说是从容关闭。有啥用呢?来看代码吧
[mapan@localhost TCP]$ lsclient.cpp makefile server.cpp[mapan@localhost TCP]$ cat server.cpp #include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <malloc.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/ioctl.h>#include <stdarg.h>#include <fcntl.h>#include <sys/types.h>#include <sys/wait.h>#include <netinet/in.h>#include <arpa/inet.h>#include <signal.h>#define MAXLINE 4096int main(){ int listenfd,connfd; pid_t childpid; socklen_t clilen; struct sockaddr_in cliaddr,servaddr; listenfd=socket(AF_INET,SOCK_STREAM,0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_addr.s_addr=htonl(INADDR_ANY); servaddr.sin_port=htons(8888); bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); listen(listenfd,1); clilen=sizeof(cliaddr); connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&clilen); char recvBuf[100]={0}; char sendBuf[100]={0}; getchar(); recv(connfd,recvBuf,100-1,0); printf("%s\n",recvBuf); scanf("%s",sendBuf); send(connfd,sendBuf,strlen(sendBuf)+1,0); printf("sendBuf=%s",sendBuf); getchar(); getchar(); close(connfd); close(listenfd); return 0;}[mapan@localhost TCP]$ cat client.cpp #include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <malloc.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/ioctl.h>#include <stdarg.h>#include <fcntl.h>#include <sys/types.h>#include <sys/wait.h>#include <netinet/in.h>#include <arpa/inet.h>#include <signal.h>#define MAXLINE 4096int main(){ int sockfd; struct sockaddr_in servaddr; sockfd=socket(AF_INET,SOCK_STREAM,0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(8888); servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"); int ret=connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); char sendBuf[100]={0}; char recvBuf[100]={0}; scanf("%s",sendBuf); send(sockfd,sendBuf,strlen(sendBuf)+1,0); close(sockfd); return 0;}[mapan@localhost TCP]$ cat makefile all:server clientserver.o:server.cppg++ -c server.cppclient.o:client.cppg++ -c client.cppserver:server.og++ -o server server.oclient:client.og++ -o client client.oclean:rm -f server client *.o[mapan@localhost TCP]$
执行:
[mapan@localhost TCP]$ makeg++ -c server.cppg++ -o server server.og++ -c client.cppg++ -o client client.o[mapan@localhost TCP]$ lsclient client.cpp client.o makefile server server.cpp server.o[mapan@localhost TCP]$ ./server
此时服务端卡在getchar(),不能接受数据。再打开一个窗口,运行客户端,输入数据,按回车键,此时客户端close了。
[mapan@localhost TCP]$ ./client
123
[mapan@localhost TCP]$
查看网络状态:
[mapan@localhost ~]$ netstat -na | grep 8888tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:34998 127.0.0.1:8888 FIN_WAIT2 tcp 5 0 127.0.0.1:8888 127.0.0.1:34998 CLOSE_WAIT由于服务端没有接收客户单发送的数据,所以客户单发送的数据还在服务端的接收缓冲区里面,123\0+FIN刚好5个字节。服务端按下回车键,并查看网络状态。
[mapan@localhost TCP]$ ./server 123
[mapan@localhost ~]$ netstat -na | grep 8888tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:35000 127.0.0.1:8888 FIN_WAIT2 tcp 0 0 127.0.0.1:8888 127.0.0.1:35000 CLOSE_WAIT那个5消失了,则服务端应用进程接收到了数据。然后在服务端输入1111111111,查看网络状态
[mapan@localhost ~]$ netstat -na | grep 8888tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN服务端一发送数据就直接断开连接了,因为客户端调用了close,服务端向一个已关闭的套接字发送数据(端口已没在使用,未打开),客户端直接回复RST,然后段断开连接。但是书上说:FIN_WAIT2下的主动端可以接收被动端发送过来的数据啊,但是上述情况好像和书上说的不一致。说到这里,shutdown的作用就能体现出来了。顺便说一下,close socket之后,ACK和FIN这种信号是可以传递的,它们通过协议栈接收并且判断是否接收到,close只是作用于应用进程。
改动客户端代码如下:
[mapan@localhost TCP]$ cat client.cpp #include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <malloc.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/ioctl.h>#include <stdarg.h>#include <fcntl.h>#include <sys/types.h>#include <sys/wait.h>#include <netinet/in.h>#include <arpa/inet.h>#include <signal.h>#define MAXLINE 4096int main(){ int sockfd; struct sockaddr_in servaddr; sockfd=socket(AF_INET,SOCK_STREAM,0); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(8888); servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"); int ret=connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); char sendBuf[100]={0}; char recvBuf[100]={0}; scanf("%s",sendBuf); send(sockfd,sendBuf,strlen(sendBuf)+1,0); shutdown(sockfd,SHUT_WR); recv(sockfd,recvBuf,100-1,0); printf("%s\n",recvBuf); getchar(); getchar(); close(sockfd); return 0;}
接着执行make clean && make,开启服务端和客户端,操作同上。客户端发送数据后,执行shutdown。
[mapan@localhost ~]$ netstat -na | grep 8888tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:35008 127.0.0.1:8888 FIN_WAIT2 tcp 5 0 127.0.0.1:8888 127.0.0.1:35008 CLOSE_WAIT [mapan@localhost ~]$
[mapan@localhost TCP]$ ./server 12311111111sendBuf=11111111
[mapan@localhost TCP]$ ./client 12311111111此时客户端接收到了数据,则证明客户端在FIN_WAIT2状态下是能接收到数据的。
现在大家对FIN_WAIT2状态和shutdown有了一定的了解了吧。
阅读全文
0 0
- shutdown函数和FIN_WAIT2状态
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2
- close和shutdown函数
- close和shutdown函数
- close 和shutdown 函数
- 网络编程(26)—— TIME_WAIT、FIN_WAIT1、FIN_WAIT2和CLOSE_WAIT状态的区别
- 11.close和shutdown函数
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题
- TCP状态迁移,CLOSE_WAIT & FIN_WAIT2 的问题
- 深入理解shutdown和close函数
- linux中shutdown() 和 close() 函数
- 自定义View学习一(圆形头像)
- HDU 6141 最小树形图
- 二分图模板
- java-String
- 面试总结
- shutdown函数和FIN_WAIT2状态
- NYOJ27
- 2017"百度之星"程序设计大赛
- Linux 下 MySQL安装教程
- 关于微信公众号开发上传永久素材时,提示40015
- 并查集入门--hd 1863
- Python基础
- QT中的QML元素
- php安装和使用