先说一下Linux的socket对shutdown和close的定义:
“
shutdown 可以选择关闭某个方向或者同时关闭两个方向,shutdown how = 1 or how = 2
(SHUT_WR or SHUT_RDWR),可以保证对等方接收到一个EOF字符(即发送了一个FIN段)
,而不管其他进程是否已经打开了这个套接字。而close不能保证,只有当某个sockfd的引
用计数为0,close 才会发送FIN段,否则只是将引用计数减1而已。也就是说只有当所有进
程(可能fork多个子进程都打开了这个套接字)都关闭了这个套接字,close 才会发送FIN 段
。所以说,如果是调用shutdown how = 1 ,则意味着往一个已经接收FIN的套接字中写是
允许的,接收到FIN段仅代表对方不再发送数据,但对方还是可以读取数据的,可以让对方
可以继续读取缓冲区剩余的数据。
”
shutdown在python网络编程里面的一个最典型的应用就是半开放socket,用来关闭socket的读/写/读写,并且它是可以叠加的。
它主要做两件事:
1.立即flush缓冲区,将缓冲区中的数据立刻刷出去,这样可以提前发现错误,这也是为什么很多write的操作会附加一个shutdown;
2.发送 FIN / EOF给所有socket的持有线程,告诉他们这个socket已经关闭了R/W/RW,以后所有不正确的使用都会产生一个错误。
close很简单,其实就是关闭文件描述符,socket的ref减一,显然这个只对单线程没有dup的socket起到关闭作用,对于多线程或者dup过的socket,需要将所有的skfd关闭才能起到reclaim的效果。
需要注意的一点是shutdown并不会close skfd和减少引用计数,因此不管有没有shutdown的调用,最后要回收socket还是要关闭socket。
阅读(6655) | 评论(1) | 转发(0) |