shutdown 与 close 的区别
来源:互联网 发布:历史最贵域名 编辑:程序博客网 时间:2024/05/17 07:45
最近弄一个ssl的客户端工具,客户端每条报文总是以RST结束断开连接,不是想象中的四路断开,百思不得其解,最后添加shutdown得以解决。
转了三篇文章,需要一一看下来,才会对这两个函数有个彻底的认识,特别是第三篇,得拿出源码分析才是王道!当然,结合实际验证也很重要。
转一:http://blog.csdn.net/jnu_simba/article/details/9068059
假设server和client 已经建立了连接,server调用了close, 发送FIN 段给client(其实不一定会发送FIN段,后面再说),此时server不能再通过socket发送和接收数据,此时client调用read,如果接收到FIN 段会返回0,但client此时还是可以write 给server的,write调用只负责把数据交给TCP发送缓冲区就可以成功返回了,所以不会出错,而server收到数据后应答一个RST段,表示服务器已经不能接收数据,连接重置,client收到RST段后无法立刻通知应用层,只把这个状态保存在TCP协议层。如果client再次调用write发数据给server,由于TCP协议层已经处于RST状态了,因此不会将数据发出,而是发一个SIGPIPE信号给应用层,SIGPIPE信号的缺省处理动作是终止程序。
有时候代码中需要连续多次调用write,可能还来不及调用read得知对方已关闭了连接就被SIGPIPE信号终止掉了,这就需要在初始化时调用sigaction处理SIGPIPE信号,对于这个信号的处理我们通常忽略即可,signal(SIGPIPE, SIG_IGN); 如果SIGPIPE信号没有导致进程异常退出(捕捉信号/忽略信号),write返回-1并且errno为EPIPE(Broken pipe)。
#include <unistd.h>
int close(int fd);
close 关闭了自身数据传输的两个方向。
#include <sys/socket.h>
int shutdown(int sockfd, int how);
shutdown 可以选择关闭某个方向或者同时关闭两个方向,shutdown how = 0 or how = 1 or how = 2 (SHUT_RD or SHUT_WR or SHUT_RDWR),后两者可以保证对等方接收到一个EOF字符(即发送了一个FIN段),而不管其他进程是否已经打开了这个套接字。而close不能保证,只有当某个sockfd的引用计数为0,close 才会发送FIN段,否则只是将引用计数减1而已。也就是说只有当所有进程(可能fork多个子进程都打开了这个套接字)都关闭了这个套接字,close 才会发送FIN 段。
所以说,如果是调用shutdown how = 1 ,则意味着往一个已经发送出FIN的套接字中写是允许的,接收到FIN段仅代表对方不再发送数据,但对方还是可以读取数据的,可以让对方可以继续读取缓冲区剩余的数据。
转载二:http://blog.chinaunix.net/uid-24532607-id-3014406.html
1,只要TCP栈的读缓冲里还有未读取(read)数据,则调用close时会直接向对端发送RST。
2,shutdown与socket描述符没有关系,即使调用shutdown(fd, SHUT_RDWR)也不会关闭fd,最终还需close(fd)。
3,可以认为shutdown(fd, SHUT_RD)是空操作,因为shutdown后还可以继续从该socket读取数据,这点也许还需要进一步证实。
4,在已发送FIN包后write该socket描述符会引发EPIPE/SIGPIPE。
5,当有多个socket描述符指向同一socket对象时,调用close时首先会递减该对象的引用计数,计数为0时才会发送FIN包结束TCP连接。shutdown不同,只要以SHUT_WR/SHUT_RDWR方式调用即发送FIN包。
6,SO_LINGER与close,当SO_LINGER选项开启但超时值为0时,调用close直接发送RST(这样可以避免进入TIME_WAIT状态,但破坏了TCP协议的正常工作方式),SO_LINGER对shutdown无影响。
7,TCP连接上出现RST与随后可能的TIME_WAIT状态没有直接关系,主动发FIN包方必然会进入TIME_WAIT状态,除非不发送FIN而直接以发送RST结束连接。
转载三:http://dev.riaos.com/?p=9006329
浅谈shutdown()和close()的区别
*file)
{
……
if (file->f_op
&& file->f_op->release)
file->f_op->release(inode, file);
…..
}
*sock, int how)
{
……
switch (sk->sk_state) {
case TCP_CLOSE:
err = -ENOTCONN;
/* Hack to wake up other listeners, who can poll for
POLLHUP, even on eg. unconnected UDP sockets — RR */
default:
sk->sk_shutdown
|= how;
if (sk->sk_prot->shutdown)
sk->sk_prot->shutdown(sk, how);
break;
/* Remaining two branches are temporary solution for missing
* close() in multithreaded environment. It is _not_ a good idea,
* but we have no choice until close() is repaired at VFS level.
*/
case TCP_LISTEN:
if (!(how
& RCV_SHUTDOWN))
break;
/* Fall through */
case TCP_SYN_SENT:
err = sk->sk_prot->disconnect(sk, O_NONBLOCK);
sock->state
= err ? SS_DISCONNECTING
: SS_UNCONNECTED;
break;
}
/* Wake up anyone sleeping in poll. */
sk->sk_state_change(sk);
……
}
- close与shutdown的区别
- shutdown 与 close 的区别
- 关于close与shutdown的区别
- 关于close与shutdown的区别
- socket :shutdown 与 close 函数 的区别
- linux中close与shutdown的区别
- shutdown 与 close 函数 的区别
- shutdown 与 close 函数 的区别
- Shutdown、Close的区别
- shutdown和close的区别
- shutdown和close的区别
- shutdown和close的区别
- shutdown和close的区别
- close和shutdown的区别
- close和shutdown的区别
- tcp的close与shutdown的区别引发的血案
- 套接字编程中close与shutdown的区别
- linux编程中close与shutdown的区别
- Oracle之sql函数之一
- tinyxml解析UTF-8字符集的xml
- 二进制加法与减法
- WIN7下最新版Eclipse3.7中文字体很小
- JAVA——Swing
- shutdown 与 close 的区别
- activity的隐藏生命周期 仅仅执行onresume
- n-维实向量空间
- 比较 stm32的 DMA_GetITStatus 和 DMA_GetFlagStatus
- ASP.NET自定义控件开发示例(一)
- 如何打破校园网垄断现象?
- Android actionBar与Fragment结合使用Demo
- ibatis <iterate>标签
- ibatis Iterate in 使用数组