9.TCP连接关闭—close和shutdown

1.基础知识:fork与文件描述符

父进程中的文件描述符:
1.如果父进程中打开了一个文件,那么子进程不需要再打开
2.fork后,子进程和父进程指向同一个文件,此时文件引用计数为2
重点:
  fd与全局变量int num不一样,int num在父子进程中是两个相互独立/互不影响的变量
  fd在父子进程中是指向一个相同文件的变量,是同一个文件描述字

2.shutdown()和close()的主要区别:

1)close关闭[读|写]两个方向,shutdown可以选择的关闭[读写]方向
2)shutdown()不能用于TCP_CLOSE状态的套接字,否则会返回ENOTCONN错误
3)引用计数
	[1]shutdown()只是关闭连接,并不会使引用计数减少
	[2]close有文件描述符引用计数的概念:当且仅当文件描述符的引用计数减为
	   零时,调用close才会调用sys_close系统调用
4)案例: /*问题:父进程调用close关闭了newconn,请问大家,TCPIP协议有
      没有向对等方发送FIN命令结束报文呢?如果没发送,为什么没发送呢?*/
  while(1){  
    if((newconn=accept(sockfd,(struct sockaddr*)&peeraddr,&peerlen))<0){
      perror("accept");
      exit(1);
    }
    pid_t pid=fork();
    if(pid<0){
      close(newconn);
      perror("fork");
    }
    else if(pid>0){ //parent
      close(newconn); /*问题:父进程调用close关闭了newconn,请问大家,TCPIP协议有
      没有向对等方发送FIN命令结束报文呢?如果没发送,为什么没发送呢?*/
    }
    else if(pid==0){//child 
     	... ...
    } 
  }  
  答案:TCPIP协议没有向对等方发送FIN命令结束报文!
	  因为,父子进程的文件描述符[指向同一个文件,该文件描述符的引用计数为2],调用close
函数仅仅使得引用计数-1,因为引用计数!=0,因此没有真正的调用系统调用函数sys_close去
进行TCP的四次挥手===>并没有发送FIN命令结束报文

3.shutdown

int shutdown(int socket, int how);
how:
	SHUT_RD
	SHUT_WR
	SHUT_RDWR

猜你喜欢

转载自blog.csdn.net/weixin_36750623/article/details/83217433