socket shutdown和close的区别
http://www.jianshu.com/p/eecab8d50697
shutdown() doesn't actually close the file descriptor—it just changes its usability. To free a socket descriptor, you need to use close().
shutdown是一种优雅地单方向或者双方向关闭socket的方法。 而close则立即双方向强制关闭socket并释放相关资源。
如果有多个进程共享一个socket,shutdown影响所有进程,而close只影响本进程。
以下均基于单进程socket。
服务端调用shutdown()
server调用shutdown(),此时任何后续的send,recv都是无效的(根据关闭发送还是关闭接收有所不同)。shutdown本身并不影响底层,也就是说,此前发出的异步send/recv不会返回。其次,在所有已发送的包被client确认后,server会发送FIN包给client,开始TCP四次挥手过程。
注意不管是关闭发送还是关闭接收,server端均向client端发送FIN报文。client 端收到FIN报文后,并不知道server端以何种方式shutdown,甚至不知道server端是shutdown还是close。
- client端收到FIN报文之后,详见下文叙述......
服务端调用close()
通过参数设置不同,调用close会出现如下A,B两种情况:
A. 向客户端发送一个RST报文,丢弃本地缓冲区的未读数据,关闭socket并释放相关资源,此种方式为强制关闭。(l_onoff为非0,l_linger为0,)
B. 向客户端发送一个FIN报文,收到client端FIN ACK后,进入了FIN_WAIT_2阶段,可参考TCP四次挥手过程,此种方式为优雅关闭。如果在l_linger的时间内仍未完成四次挥手,则强制关闭。( l_onoff 为非0,l_linger为非0)
FIN与RST
若server端发送FIN报文后没有收到client端的FIN ACK,会两次重传FIN报文,若一直收不到client端的FIN ACK,则会给client端发送RST信号,关闭socket并释放资源。(不同系统实现可能会不同)
client收到FIN信号后,再调用read函数会返回0。因为FIN的接收,表明client端以后再无数据可以接收,对方发来FIN,表明对方不在发送数据了。
(注意所有FIN及ACK报文均由操作系统自动完成发送接收)
client收到FIN后,会发送应答ack报文,表明收到server的FIN报文,server收到ack报文之后,就进入了FIN_WAIT_2阶段。
根据tcp协议,向一个 FIN_WAIT2 状态的 TCP写入数据是没有问题的,所以此时client可以调用write函数,写入到发送缓冲区,并由tcp连接,发送到server的接收缓冲区。由于server端已经关闭了socket,所以此时的server接收缓冲区的内容都被抛弃,同时server端返回RST给客户端。
client端如何知道已经接收到RST报文?
server发送RST报文后,并不等待从client端接收任何ack响应,直接关闭socket。而client端收到RST报文后,也不会产生任何响应。client端收到RST报文后,程序行为如下:
- 阻塞模型下,内核无法主动通知应用层出错,只有应用层主动调用read()或者write()这样的IO系统调用时,内核才会利用出错来通知应用层对端已经发送RST报文。
- 非阻塞模型下,select或者epoll会返回sockfd可读,应用层对其进行读取时,read()会报RST错误。
通过read write函数出错返回后,获取errno来确定对端是否发送RST信号。
- client收到RST报文后应如何处理?
client端收到RST信号后,如果调用read函数读取,则会返回RST错误。在已经产生RST错误的情况下,继续调用write,则会发生epipe错误。此时内核将向客户进程发送 SIGPIPE 信号,该信号默认会使进程终止,通常程序会异常退出(未处理SIGPIPE信号的情况下)。
在收到server发送RST报文的情况下,client端的任何read write都是毫无意义的。
作者:dacheng
链接:http://www.jianshu.com/p/eecab8d50697
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
socket shutdown和close的区别的更多相关文章
- socket shutdown 与 close 函数 的区别
假设server和client 已经建立了连接,server调用了close, 发送FIN 段给client(其实不一定会发送FIN段,后面再说),此时server不能再通过socket发送和接收数据 ...
- shutdown和close的区别
[shutdown和close的区别] 当所有的数据操作结束以后,你可以调用close()函数来释放该socket,从而停止在该socket上的任何数据操作:close(sockfd); 你也可以调用 ...
- JAVA线程池shutdown和shutdownNow的区别
一.区别介绍 shutDown() 当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态.此时,则不能再往线程池中添加任何任务,否则将会抛出RejectedExecutionExcept ...
- C# Socket和TCP连接的区别
网络通信七层参考模型介绍: 物理层: HUB,网线 链路层: MAC,ARP,交换机 网络层:IP,ICMP,IGMP,路由器 传输层: TCP,UDP 会话层: HTTP,SMTP,FTP,POP3 ...
- WebSocket(二)-WebSocket、Socket、TCP、HTTP区别
原文地址:Socket 与 WebSocket 1. 概述 WebSocket 是为了满足基于 Web 的日益增长的实时通信需求而产生的.在传统的 Web 中,要实现实时通信,通用的方式是采用 HTT ...
- 基于UDP的socket tcp和udp的区别(小白进击篇)
目录 16.基于udp协议的socket通信 为什么udp不会有粘包现象 DGRAM datagram#数据报文 发送sento (发送的信息,发送给的地址) 接收revefrom 客户端 服务端 t ...
- Socket shutdown close简要分析
shutdown 系统调用关闭连接的读数据通道 写数据通道 或者 读写数据通道: 关闭读通道:丢弃socket fd 读数据以及调用shutdown 后到达的数据: 关闭写通道:不同协议处理不同:t ...
- socket和http有什么区别?
socket是网络传输层的一种技术,跟http有本质的区别,http是应用层的一个网络协议.使用socket技术理论上来讲, 按照http的规范,完全可以使用socket来达到发送http请求的目的, ...
- init shutdown reboot poweroff halt区别
init 首先看看LINUX系统几种运行级别# 0 - 停机(千万别把initdefault设置为0,否则系统永远无法启动)# 1 - 单用户模式# 2 - 多用户,没有 NFS# 3 - 完全多用户 ...
随机推荐
- MySQL-数据操作-增删改查
1.增加: insert into 表 (列名,列名...) values (值,值,值...) insert into 表 (列名,列名...) values (值,值,值...),(值,值,值.. ...
- gbk文件转为utf8文件
convmv -f gbk -t utf- --notest -r ./
- 利用gcc自带的功能-fstack-protector检测栈溢出及其实现【转】
转自:https://www.cnblogs.com/leo0000/p/5719186.html 最近又遇到了一个崩溃,栈回溯非常怪异. /lib/i386-linux-gnu/libc.so.6( ...
- CentOS 5.x 键盘布局改为日语
CentOS 5.x 直接在系统设置界面修改键盘布局,可能不起作用,需要按如下步骤修改配置文件. 1. /etc/sysconfig/keyboard KEYTABLE="jp106&quo ...
- PHP实现 APP端微信支付功能
1.我封装好的一个支付类文件,多余的东西都去除掉了,并且把配置参数放到了这个支付类中,只需要修改Weixinpayandroid方法内的几个参数就可以直接复制使用: class Wxpayandroi ...
- JS文件上传神器bootstrap fileinput详解
Bootstrap FileInput插件功能如此强大,完全没有理由不去使用,但是国内很少能找到本插件完整的使用方法,于是本人去其官网翻译了一下英文说明文档放在这里供英文不好的同学勉强查阅.另外附上一 ...
- hdu 1394 求一个序列的最小逆序数 单点增 区间求和
题目的意思就好比给出一个序列 如:0 3 4 1 2 设逆序数初始n = 0: 由于0后面没有比它小的,n = 0 3后面有1,2 n = 2 4后面有1,2,n = 2+2 = 4: 所以该序列逆序 ...
- 原 nc在centos7上的安装和简单使用
https://blog.csdn.net/qq_16414307/article/details/50291341 https://www.cnblogs.com/rocky-AGE-24/p/69 ...
- 【转载】Java与C++语言在作用域上的差异浅析
http://developer.51cto.com/art/200906/126199.htm 差异一:变量作用域的不同 如下面这段程序代码是符合C++语言的语法要求的.其可以在C语言下正常运行.但 ...
- java中static,final,private方法的继承多态问题
父类中的final private方法不能被继承,父类中的static方法可以被继承,但是不能重写,这三者都属于前期绑定,java中除了这三种以及构造方法之外剩下的都是后期绑定(运行是绑定). 当父 ...