从TCP协议角度来看,一个已建立的TCP连接有两种关闭方式,一种是正常关闭,即四次挥手关闭连接;还有一种则是异常关闭,我们通常称之为连接重置(RESET)。

首先说一下正常关闭时四次挥手的状态变迁,关闭连接的主动方状态变迁是FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT,而关闭连接的被动方的状态变迁是CLOSE_WAIT->LAST_ACK->TIME_WAIT。在四次挥手过程中ACK包都是协议栈自动完成的,而FIN包则必须由应用层通过closesocket或shutdown主动发送,通常连接正常关闭后,recv会得到返回值0,send会得到错误码10058。

除此之外,在我们的日常应用中,连接异常关闭的情况也很多。比如应用程序被强行关闭、本地网络突然中断(禁用网卡、网线拔出)、程序处理不当等都会导致连接重置,连接重置时将会产生RST包,同时网络络缓冲区中未接收(发送)的数据都将丢失。连接重置后,本方send或recv会得到错误码10053(closesocket时是10038),对方recv会得到错误码10054,send则得到错误码10053(closesocket时是10054)。

操作系统为我们提供了两个函数来关闭一个TCP连接,分别是closesocket和shutdown。通常情况下,closesocket会向对方发送一个FIN包,但是也有例外。比如有一个工作线程正在调用recv接收数据,此时外部调用closesocket,会导致连接重置,同时向对方发送一个RST包,这个RST包是由本方主动产生的。

shutdown可以用来关闭指定方向的连接,该函数接收两个参数,一个是套接字,另一个是关闭的方向,可用值为SD_SEND,SD_RECEIVE和SD_BOTH。方向取值为SD_SEND时,无论socket处于什么状态(recv阻塞,或空闲状态),都会向对方发送一个FIN包,注意这点与closesocket的区别。此时本方进入FIN_WAIT_2状态,对方进入CLOSE_WAIT状态,本方依然可以调用recv接收数据;方向取值为SD_RECEIVE时,双发连接状态没有改变,依然处于ESTABLISHED状态,本方依然可以send数据,但是,如果对方再调用send方法,连接会被立即重置,同时向对方发送一个RST包,这个RST包是被动产生的,这点注意与closesocket的区别。

关闭TCP连接的学问相关推荐

  1. 客户端能不等四次挥手就强制关闭 TCP 连接吗?

    在<Go 网络编程和 TCP 抓包实操>Conn.Close() 方法发起了关闭 TCP 连接的请求,这是一种默认的关闭连接方式. 默认关闭需要四次挥手的确认过程,这是一种"商量 ...

  2. 如何正确关闭TCP连接

    文章目录 Ⅰ. 如何正确关闭TCP连接示例程序 Ⅱ. b 程序数据接收不完整的原因可能是 a 程序没有发送完所有的数据(tcp send buffer中的数据)就退出了 Ⅲ. 尝试让程序a中所有排队的 ...

  3. linux 使用bash命令关闭TCP连接

    在进程中关闭tcp连接比较简单,直接调用socket的API即可关闭,或不发送心跳机制. 有时候为了测试异常环境,在不断网的情况下,如何使用bash命令关闭TCP的连接呢? 下面谈两种使用bash命令 ...

  4. 主动关闭TCP连接的一方为什么要有TIME_WAIT状态

    TCP连接是全双工通信,主动方和被动方都需要自主关闭通信链路,TCP正常情况下连接断开会进行四次挥手(流程如上图所示): 1.由主动断开方发起FIN 2.被动方回复ACK 3.待被动方数据传输完成,被 ...

  5. 关闭tcp连接时有时发送FIN有时发送RST

    使用http 发送同一个包,sleep 20 秒后再读取数据,htpp设置1s的超时时间,超时后会关闭socket ,可是有时发送RST,有时发送FIN,如下图: 后来google 了一把,发现 tc ...

  6. php curl 关闭tcp连接,BASH CURL:顺序运行时,请勿关闭请求之间的连接

    我正在尝试编写一个BASH命令,该命令使用CURL将GET请求发送到两个不同的网页,但使用相同的连接.对我来说,就像向登录页面发送GET请求以向服务器进行身份验证,然后第二个请求模仿自动重定向到主页, ...

  7. muduo网络库学习(五)服务器监听类Acceptor及Tcp连接TcpConnection的建立与关闭

    通常服务器在处理客户端连接请求时,为了不阻塞在accept函数上,会将监听套接字注册到io复用函数中,当客户端请求连接时,监听套接字变为可读,随后在回调函数调用accept接收客户端连接.muduo将 ...

  8. Linux网络协议栈:关闭一个还有没发送数据完的TCP连接

    <监视和调整Linux网络协议栈:接收数据> <监控和调整Linux网络协议栈的图解指南:接收数据> <Linux网络 - 数据包的接收过程> <Linux网 ...

  9. Linux 内核协议栈之TCP连接关闭

    Close行为: 当应用程序在调用close()函数关闭TCP连接时,Linux内核的默认行为是将套接口发送队列里的原有数据(比如之前残留的数据)以及新加入 的数据(比如函数close()产生的FIN ...

最新文章

  1. python requests模块使用
  2. (11/24) css进阶:Less文件的打包和分离
  3. 关于树,各种平衡树查找树的资料合集~~
  4. android中心点旋转晃动_Android:如何在中心点上旋转位图
  5. mfc 创建线程函数AfxBeginThread,线程中访问mfc控件
  6. ICC Scenario Definition
  7. 中国恒大:半个月网上售房近10万套 认购金额1026.7亿元
  8. 快讯:阿里巴巴加入JCP执行委员会
  9. C#复制文件夹下的所有内容到另一个文件夹
  10. ios音乐播放器使用综述
  11. python抖音涨粉代码_抖音最火表白代码
  12. Java 二叉树的层序遍历
  13. 快递是如何被送到你手里的?一文读懂风口上的仓储自动化
  14. 贝多芬第九交响曲,卡拉扬63年版,第四乐章演唱部分歌词文件
  15. 【第二届集成电路EDA备赛】一、Icarus Verilog(iverilog)快速上手使用(基于windows)
  16. 基于tensorflow和卷积神经网络的电影推荐系统的实现
  17. 利用RSS进行学术期刊订阅
  18. 小米pro显示无服务器,【解决】小米WiFi放大器pro连接不稳定/连接后无网络的问题!!!...
  19. edge阅读文章实用技巧
  20. 男人必须明白的20个道理

热门文章

  1. spring框架中@PostConstruct的实现原理
  2. DTO – 服务实现中的核心数据
  3. java layoutmanager_Java Swing 探索(一)LayoutManager
  4. cpc卡内计费信息异常包括_今日头条信息流广告投放效果好吗?信息流广告计费方式怎么收费?...
  5. Serverless简介
  6. 设计模式(二) 模板方法
  7. install-info - 更新 info/dir 项
  8. POJ 1276 完全背包
  9. Deque - leetcode 【双端队列】
  10. java+eclipse+selenium环境搭建