【linux】close与shutdown
来源:互联网 发布:岁寒然后知松柏下一句 编辑:程序博客网 时间:2024/06/10 17:52
了解close与shutdown区别,我们先回忆下文件描述符与进程的关系。代码如下:
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>int main(){ char *pathname = "a.txt"; char father[] = "this isffffffffffffffffif father"; char son[] = "this is sssssssssssssssssssssssssss son"; int fd; int re; fd = open(pathname,O_CREAT|O_RDWR); pid_t pid = fork(); if(pid > 0) { write(fd,father,sizeof(father)); re = close(fd); printf("father re = %d \n",re); re = close(fd); printf("father re 2 = %d \n",re); }else if(pid == 0) { sleep(1); write(fd,son,sizeof(son)); re = close(fd); printf("son re = %d \n",re); }}
多进程中,父子进程都会有独立的空间(PCB,代码段,数据段,BSS,还有堆栈段),但是这时候文件描述符是共用的,都可以往同一个文件写内容。但是引入了一个计数器。如下图:refcnt:2,我们必须close两次才能把文件彻底关掉。
了解了如上内容,我们可以继续往下:
1.server代码如下:收到第一个字符为 1 后 close 当前进程文件描述符,关注下最后一行。server收数据
#include<stdio.h>#include<stdlib.h>#include <sys/types.h> /* See NOTES */#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include<string.h>#include<signal.h>void handler(int num){ //wait(NULL); int pp_pid = 0; while((pp_pid = waitpid(-1,NULL,WNOHANG)) > 0) { printf("break pid :%d \n",pp_pid); } exit(0);}int main(){ struct sockaddr_in addr; struct sockaddr_in addr_peer; struct in_addr ip; inet_aton("127.0.0.1",&ip); addr.sin_family = AF_INET; addr.sin_port =htons(8001); addr.sin_addr = ip; int sockfd = 0; int conn =0; int re = 0; char buf[1024] = {0}; char buf_write[1024] = {0}; signal(SIGCHLD,handler); sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd == -1) { perror("sockfd error \n"); } re = bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)); if(re == -1) { perror("bind error"); } conn = listen(sockfd,SOMAXCONN); if(conn == -1) { perror("listen error \n"); } //while(1) { int len = sizeof(struct sockaddr_in); conn =accept(sockfd,(struct sockaddr *)&addr_peer,&len); printf("port:%u \n",ntohs(addr_peer.sin_port)); pid_t pid = fork(); if(pid == 0) { int ret = 0; while(1) { ret = read(conn,buf,sizeof(buf)); if(buf[0] == '1') { close(conn); } fputs(buf,stdout); memset(buf,0,sizeof(buf)); } }else if(pid > 0) { while(fgets(buf_write,sizeof(buf_write),stdin))!= NULL) { write(conn,buf_write,sizeof(buf_write)); } } }
client代码如下:client负责读写数据:
#include<stdio.h>#include<stdlib.h>#include <sys/types.h> /* See NOTES */#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include<signal.h>#include<string.h>void handler(int num){ printf("num = %d \n",num);}int main(){ struct sockaddr_in addr; struct in_addr ip; inet_aton("127.0.0.1",&ip); addr.sin_family = AF_INET; addr.sin_port =htons(8001); addr.sin_addr = ip; int re = 0,i = 0,conn =0,sockfd = 0; char buf[1024] ={0}; char buf_read[1024] = {0}; signal(SIGPIPE,handler); { sockfd = socket(AF_INET, SOCK_STREAM, 0); if(sockfd == -1) { perror("sockfd error \n"); } conn = connect(sockfd, (const struct sockaddr *)&addr,sizeof(struct sockaddr_in)); if(conn == -1) { perror("conn error \n"); } } pid_t pid = fork(); if(pid == 0) { while((fgets(buf,sizeof(buf),stdin)) != NULL) { write(sockfd,buf,sizeof(buf)); memset(buf,0,sizeof(buf)); } }else if(pid > 0) { while(1) { re = read(sockfd,buf_read,sizeof(buf_read)); if(re == 0) { close(sockfd); printf("peer is break \n"); } fputs(buf_read,stdout); memset(buf_read,0,sizeof(buf_read)); } } }
此时client发送1 后,server收到后关闭文件描述符,但是看状态:
tcp 0 0 localhost:49021 localhost:8001 ESTABLISHEDtcp 3072 0 localhost:8001 localhost:49021 ESTABLISHED
此时只是关闭了client的写和servser可以的读。server发数据client仍然可以读到。只有两个进程都关闭了文件描述符,才会发FIN字段,开始断开的4次握手。
close了解了
开始了解下shutdown。
SHUT_RD:关闭连接的读端。也就是该套接字不再接受数据,任何当前在套接字接受缓冲区的数据将被丢弃。进程将不能对该
套接字发出任何读操作。对TCP套接字该调用之后接受到的任何数据将被确认然后无声的丢弃掉。
SHUT_WR:关闭连接的写端,进程不能在对此套接字发出写操作
SHUT_RDWR:相当于调用shutdown两次:首先是以SHUT_RD,然后以SHUT_WR
使用close中止一个连接,但它只是减少描述符的参考数,并不直接关闭连接,只有当描述符的参考数为0时才关闭连接。
shutdown可直接关闭描述符,不考虑描述符的参考数,可选择中止一个方向的连接。
//更改server代码,将close改为shutdown while(1) { ret = read(conn,buf,sizeof(buf)); if(buf[0] == '1') { //close(conn); shutdown(conn,SHUT_RDWR); } fputs(buf,stdout); memset(buf,0,sizeof(buf)); }
查看状态
tcp 0 0 localhost:8001 localhost:49024 FIN_WAIT2 tcp 0 0 localhost:49024 localhost:8001 CLOSE_WAIT
阅读全文
0 0
- 【linux】close与shutdown
- linux中close与shutdown的区别
- Linux socket关闭连接shutdown与close
- Linux socket关闭连接shutdown与close
- linux socket close shutdown
- close与shutdown
- [zz] Linux socket关闭连接shutdown与close
- linux下socket编程:区分close()与shutdown()
- linux网络编程之shutdown() 与 close()函数详解
- linux网络编程之shutdown() 与 close()函数详解
- linux网络编程之shutdown() 与 close()函数详解
- linux网络编程之shutdown() 与 close()函数详解
- linux网络编程之shutdown() 与 close()函数详解
- linux网络编程之shutdown() 与 close()函数详解
- linux编程中close与shutdown的区别
- linux网络编程之shutdown() 与 close()函数详解
- Linux网络编程10(3) -- close 与 shutdown
- close与shutdown的区别
- RSA 算法原理(一)
- java发送GET、POST请求
- Apache Commons:功能齐全的通用Java组件
- Python-11 字符串格式化
- 欧拉函数-LightOJ1007
- 【linux】close与shutdown
- C语言 实现两种排序方法
- 感谢 Flash 所做的一切
- 有一个任务队列,分别有A、B、C三种类型的任务,设计一种功能,让三种任务分别按照x:y:z(具体比例可配置)的比例进行执行
- android ndk 01 c语言 基本数据类型_输入输出_指针
- IntrospectorCleanupListener作用
- 0726 java入门
- laravel5.4 导入导出excel /.xls
- oracle与mysql数据库基本数据类型--介绍与区别