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