下面是对 譬如  “CLOSE_WAIT” 现象的一些解释:

主动关闭方和被动方经历的状态:
FIN_WAIT_1(主动关闭一方): 当SOCKET在ESTABLISHED状态时,它想主动关
     闭连接,向对方发送了FIN报文,此时该SOCKET即进入到
     FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态
FIN_WAIT_2(主动关闭一方):上面已经详细解释了这种状态,实际上FIN_WAIT_2
     状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接
TIME_WAIT(主动关闭一方): 表示收到了对方的FIN报文,并发送出了ACK报文
     就等2MSL(2倍最大生存时间)后即可回到CLOSED可用状态了。
CLOSE_WAIT(被动关闭一方): 这种状态的含义其实是表示在等待关闭。当对方
     close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应
      一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对
     方,如果没有的话,那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。
LAST_ACK(被动关闭一方): 它是被动关闭一方在发送FIN报文后,最后等待对方的
     ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态

-------------------------------------------------------------------

下面是 socket的close和shutdown 的一些说明:

在Linux socket关闭连接的方法有两种分别是shutdown和close,首先看一下shutdown的定义

#include<sys/socket.h>

int shutdown(int sockfd,int how);

how的方式有三种分别是

SHUT_RD(0):关闭sockfd上的读功能,此选项将不允许sockfd进行读操作。

SHUT_WR(1):关闭sockfd的写功能,此选项将不允许sockfd进行写操作。

SHUT_RDWR(2):关闭sockfd的读写功能。

成功则返回0,错误返回-1,错误码errno:EBADF表示sockfd不是一个有效描述符;ENOTCONN表示sockfd未连接;ENOTSOCK表示sockfd是一个文件描述符而不是socket描述符。

close的定义如下:

#include<unistd.h>

int close(int fd);

关闭读写。

成功则返回0,错误返回-1,错误码errno:EBADF表示fd不是一个有效描述符;EINTR表示close函数被信号中断;EIO表示一个IO错误。

下面摘用网上的一段话来说明二者的区别:

close-----关闭本进程的socket id,但链接还是开着的,用这个socket id的其它进程还能用这个链接,能读或写这个socket id

shutdown--则破坏了socket 链接,读的时候可能侦探到EOF结束符,写的时候可能会收到一个SIGPIPE信号,这个信号可能直到

socket buffer被填充了才收到,shutdown还有一个关闭方式的参数,0 不能再读,1不能再写,2 读写都不能。

socket 多进程中的shutdown, close使用

当所有的数据操作结束以后,你可以调用close()函数来释放该socket,从而停止在该socket上的任何数据操作:

close(sockfd);

你也可以调用shutdown()函数来关闭该socket。该函数允许你只停止在某个方向上的数据传输,而一个方向上的数据传输继

续进行。如你可以关闭某socket的写操作而允许继续在该socket上接受数据,直至读入所有数据。

int shutdown(int sockfd,int how);

Sockfd是需要关闭的socket的描述符。参数 how允许为shutdown操作选择以下几种方式:

SHUT_RD:关闭连接的读端。也就是该套接字不再接受数据,任何当前在套接字接受缓冲区的数据将被丢弃。进程将不能对该

套接字发出任何读操作。对TCP套接字该调用之后接受到的任何数据将被确认然后无声的丢弃掉。

SHUT_WR:关闭连接的写端,进程不能在对此套接字发出写操作

SHUT_RDWR:相当于调用shutdown两次:首先是以SHUT_RD,然后以SHUT_WR

使用close中止一个连接,但它只是减少描述符的参考数,并不直接关闭连接,只有当描述符的参考数为0时才关闭连接。

shutdown可直接关闭描述符,不考虑描述符的参考数,可选择中止一个方向的连接。

注意:

1>. 如果有多个进程共享一个套接字,close每被调用一次,计数减1,直到计数为0时,也就是所用进程都调用了close,套接字将被释放。

2>. 在多进程中如果一个进程中shutdown(sfd, SHUT_RDWR)后其它的进程将无法进行通信. 如果一个进程close(sfd)将不会影响到其它进程. 得自己理解引用计数的用法了. 有Kernel编程知识的更好理解了.

更多关于close和shutdown的说明

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结束连接。

wainiwann

socket关闭状态问题的更多相关文章

  1. 怎样实时判断socket连接状态?

    对端正常close socket,或者进程退出(正常退出或崩溃),对端系统正常关闭 这种情况下,协议栈会走正常的关闭状态转移,使用epoll的话,一般要判断如下几个情况 处理可读事件时,在循环read ...

  2. DWZ(JUI) 教程 左侧栏默认是关闭状态的问题

    DWZ(JUI) 教程 左侧栏默认是关闭状态的问题,初始化是全屏状态,只需简单处理就可以了 $(function(){ DWZ.init("dwz.frag.xml", { log ...

  3. 通过注册表检测UAC是否处于关闭状态(不弹窗)

    注册表路径: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System UAC各级别对应的注册表值: 从 ...

  4. 解决set /p yn= 接受键盘输入导致ECHO 处于关闭状态的问题

    今天写了一个自动更新程序的批处理脚本,但是有个变量一直赋值有问题.弄了一个下午终于找到原因及解决方法: ----转载要说明来自:博客园--邦邦酱好 哦 有问题的代码如下: @echo off echo ...

  5. js判断获取浏览器关闭状态

    如题,js获取浏览器关闭状态,可实现判断选择是否关闭. <html> <head> <title> </title> </head> < ...

  6. [转]mysql在已有无分区表增加分区,mysql5.5才有,可以是innodb_file_per_table关闭状态.

    FROM : http://blog.csdn.net/sunvince/article/details/7752662 mysql5.1的时候新增的partition,解决了比较简单的shardin ...

  7. wmware7安装xp错误:虚拟CPU已经入关闭状态

    wm7安装xp错误提示: 虚拟CPU已经入关闭状态.这会造成物理计算机重新启动.这可能是虚拟机操作系统的错误或VMware Workstation软件中的一个配置不正确. 这种情是硬盘模式为AHCI模 ...

  8. (转)在server 2008R2组策略设置所有域计算机防火墙都处于更关闭状态

    组策略在域控中相当重要,我们可以下放一个组策略去统一管理下面客户端的配置,具体配置如下: 首先点击开始____管理工具____组策略管理 防火墙关闭完之后我们该如何到客户端验证呢? 首先我们需要现在客 ...

  9. socket关闭动作以及socket状态的总结

    主要部分,四次握手: 断开连接其实从我的角度看不区分客户端和服务器端,任何一方都可以调用close(or closesocket)之类的函数开始主动终止一个连接.这里先暂时说正常情况.当调用close ...

随机推荐

  1. export default用法

    // test.js export default { name: 'zs', age: 20 } 或是 // test.js var info = { name: 'zs', age: 20 } e ...

  2. Servlet3.0上传

    1.上传对表单限制 *method=post *Enctype=multipart/form-data,它的默认值是:application/x-www-form-urlencoded 表单中需要添加 ...

  3. oracle ceil函数

    ceil和floor函数在一些业务数据的时候,有时还是很有用的. ceil(n) 取大于等于数值n的最小整数: floor(n)取小于等于数值n的最大整数 如下例子 SQL> select ce ...

  4. const函数

    1. const修饰成员函数:表示不可以修改成员变量 class test{ public: test(){ i_ = ; } int Get() const{ //i_ = 0; //error:不 ...

  5. 思路 一般创建展示类时候 例如page类 会在网页上新增多个对应字段的隐藏域 用于存储值

    思路 一般创建展示类时候 例如page类 会在网页上新增多个对应字段的隐藏域 用于存储值

  6. Tomcat的四种web应用部署方式详解

    在Tomcat中有四种部署Web应用的方式,简要的概括分别是: (1)利用Tomcat自动部署 (2)利用控制台进行部署 (3)增加自定义的Web部署文件(%Tomcat_Home%\conf\Cat ...

  7. 爬虫_拉勾网(selenium)

    使用selenium进行翻页获取职位链接,再对链接进行解析 会爬取到部分空列表,感觉是网速太慢了,加了time.sleep()还是会有空列表 from selenium import webdrive ...

  8. Android 2019最新面试实战总结

    Android: 今日头条屏幕适配的原理? 1:首先计算出 density,计算公式:当前设备屏幕总宽度(单位为像素)/ 设计图总宽度(单位为 dp) = densitydensity 的意思就是 1 ...

  9. 自学Zabbix4.0之路

    自学Zabbix4.0之路 01 Centos7安装Zabbix4.0步骤 02 Centos7下Zabbix3.4至Zabbix4.0的升级步骤 03 Zabbix4.0添加cisco交换机基本监控 ...

  10. angularjs优化方略

    angular优化方略,闲的没事想重构的人来瞅瞅. 1.减少$watch 减少$watch,减少$watch,减少$watch.不仅仅是$watch监听,还有ng-model,别闲的没事就加个ng-m ...