从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的区别。

如何才能正确的关闭Socket连接相关推荐

  1. mysql 80070057_远程主机关闭了连接。错误代码是 0x80070057,与远程主机通信时发生错误。错误代码是 0x80070057...

    远程主机关闭了连接.错误代码是 0x80070057,与远程主机通信时发生错误.错误代码是 0x80070057 突然在异常错误日志中看到这个错误,虽然在测试中发现不影响流的传输,但是不代表没错误,解 ...

  2. Java面试题17 牛客 下面哪个选项正确创建socket连接?

    Java面试题17 牛客 下面哪个选项正确创建socket连接? Socket s = new Socket(8080); Socket s = new Socket("192.168.1. ...

  3. 如何正确关闭TCP连接

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

  4. 关于使用druid数据源连接Oracle导致的SQLRecoverableException(socket read timeout,关闭的连接等)

    背景 数据源初始化后,获取Oracle的连接进行查询操作,相隔 半个小时 左右,再次对同一数据库进行查询操作. 问题 第二次查询的时候,就会出现如下一些异常情况 2019-06-05 14:17:58 ...

  5. Socket连接与HTTP连接

    我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP.FTP.T ...

  6. 一篇搞懂TCP、HTTP、Socket、Socket连接池

    上一篇:闲鱼面试官:Thread.sleep(0) 到底有什么用?我:有点懵~ 作者:数澜科技 链接:https://www.jianshu.com/p/e47a766e03da 前言:作为一名开发人 ...

  7. 作为后端开发人员应该懂的TCP、HTTP、Socket、Socket连接池,一文详解丨Linux后端开发

    前言:作为一名开发人员我们经常会听到HTTP协议.TCP/IP协议.UDP协议.Socket.Socket长连接.Socket连接池等字眼,然而它们之间的关系.区别及原理并不是所有人都能理解清楚,这篇 ...

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

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

  9. Http和Socket连接区别(ZT)

    1.TCP连接 要想明白Socket连接,先要明白TCP连接.手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上 ...

最新文章

  1. 大厂技术文档:Redis+Nginx+Spring全家桶+Dubbo精选
  2. Xcode 6.x 上开发APP 兼容 iOS7
  3. 重学java基础第十七课:java开发环境搭建
  4. nginx 学习笔记【持续更新...】
  5. 脉冲宽度调制pdm_PWM (脉冲宽度调制)原理与实现
  6. Java基础之深入认识hashCode和equals
  7. Oracle11g手动创建数据库方法
  8. TechNet Magazine/TechNet杂志
  9. 获取任务管理器中进程的Memory(Private Working Set)
  10. 向数据源DataTable 中添加新的一列,并向其赋值
  11. [转]VS2013+简单稀疏光束调整库SSBA配置(64位编译)
  12. 解决谷歌浏览器flash插件已被屏蔽
  13. 微信接口类php,【微信接口库】分享10个常用的php微信接口类
  14. ROS入门教程(六)—— Gazebo仿真
  15. 给Android程序员的一些面试建议
  16. 全球与中国大麻化妆品市场深度研究分析报告
  17. windows 10企业版windows Defender无法使用
  18. 网页抓取及信息提取(一)
  19. 数云荣登乌镇互联网大会2016中国大数据创新企业50强
  20. 怎么启动和关闭Mysql?

热门文章

  1. Gentoo下keepalived+LVS实验
  2. 脱机多维数据集CUB文件的生成
  3. 【前端】react and redux教程学习实践,浅显易懂的实践学习方法。
  4. Fortinet宣布收购AccelOps
  5. 针对上上篇博文--仿优酷菜单---的bug修改
  6. 线程技术 ☞ Future模式
  7. ns 25的IKE模式ipsec ***配置
  8. centos源码安装mysql5.7.25-boost
  9. CentOS6软件包管理
  10. error: No curses/termcap library found的解决办法