如何才能正确的关闭Socket连接
从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连接相关推荐
- mysql 80070057_远程主机关闭了连接。错误代码是 0x80070057,与远程主机通信时发生错误。错误代码是 0x80070057...
远程主机关闭了连接.错误代码是 0x80070057,与远程主机通信时发生错误.错误代码是 0x80070057 突然在异常错误日志中看到这个错误,虽然在测试中发现不影响流的传输,但是不代表没错误,解 ...
- Java面试题17 牛客 下面哪个选项正确创建socket连接?
Java面试题17 牛客 下面哪个选项正确创建socket连接? Socket s = new Socket(8080); Socket s = new Socket("192.168.1. ...
- 如何正确关闭TCP连接
文章目录 Ⅰ. 如何正确关闭TCP连接示例程序 Ⅱ. b 程序数据接收不完整的原因可能是 a 程序没有发送完所有的数据(tcp send buffer中的数据)就退出了 Ⅲ. 尝试让程序a中所有排队的 ...
- 关于使用druid数据源连接Oracle导致的SQLRecoverableException(socket read timeout,关闭的连接等)
背景 数据源初始化后,获取Oracle的连接进行查询操作,相隔 半个小时 左右,再次对同一数据库进行查询操作. 问题 第二次查询的时候,就会出现如下一些异常情况 2019-06-05 14:17:58 ...
- Socket连接与HTTP连接
我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP.FTP.T ...
- 一篇搞懂TCP、HTTP、Socket、Socket连接池
上一篇:闲鱼面试官:Thread.sleep(0) 到底有什么用?我:有点懵~ 作者:数澜科技 链接:https://www.jianshu.com/p/e47a766e03da 前言:作为一名开发人 ...
- 作为后端开发人员应该懂的TCP、HTTP、Socket、Socket连接池,一文详解丨Linux后端开发
前言:作为一名开发人员我们经常会听到HTTP协议.TCP/IP协议.UDP协议.Socket.Socket长连接.Socket连接池等字眼,然而它们之间的关系.区别及原理并不是所有人都能理解清楚,这篇 ...
- linux 使用bash命令关闭TCP连接
在进程中关闭tcp连接比较简单,直接调用socket的API即可关闭,或不发送心跳机制. 有时候为了测试异常环境,在不断网的情况下,如何使用bash命令关闭TCP的连接呢? 下面谈两种使用bash命令 ...
- Http和Socket连接区别(ZT)
1.TCP连接 要想明白Socket连接,先要明白TCP连接.手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上 ...
最新文章
- 大厂技术文档:Redis+Nginx+Spring全家桶+Dubbo精选
- Xcode 6.x 上开发APP 兼容 iOS7
- 重学java基础第十七课:java开发环境搭建
- nginx 学习笔记【持续更新...】
- 脉冲宽度调制pdm_PWM (脉冲宽度调制)原理与实现
- Java基础之深入认识hashCode和equals
- Oracle11g手动创建数据库方法
- TechNet Magazine/TechNet杂志
- 获取任务管理器中进程的Memory(Private Working Set)
- 向数据源DataTable 中添加新的一列,并向其赋值
- [转]VS2013+简单稀疏光束调整库SSBA配置(64位编译)
- 解决谷歌浏览器flash插件已被屏蔽
- 微信接口类php,【微信接口库】分享10个常用的php微信接口类
- ROS入门教程(六)—— Gazebo仿真
- 给Android程序员的一些面试建议
- 全球与中国大麻化妆品市场深度研究分析报告
- windows 10企业版windows Defender无法使用
- 网页抓取及信息提取(一)
- 数云荣登乌镇互联网大会2016中国大数据创新企业50强
- 怎么启动和关闭Mysql?