读懂TCP状态转移
读懂TCP状态转移过程,对理解网络编程颇有帮助,本文将对TCP状态转移过程进行介绍,但各状态(总共11个)含义不在本文介绍的范围,请参考文末的书目列表。
TCP状态转换图(state transition diagram)
1. 建立连接(three-way hand shake)
- 主动打开(passive open):服务器必须准备好接受外来的连接,通常通过socket、bind和listen完成。
- 被动打开(active open):客户端通过connect发起主动打开。
插句话,该文介绍的性能分析工具(sar -n TCP,ETCP 1)命令可以对主动打开和被动打开的数目进行统计,在一定程度上可以反应服务器的繁忙程度。
下图给出客户端与服务器的三次握手过程:
- 服务器准备好接受外来连接,通常通过socket、bind和listen完成。(服务器:CLOSED->LISTEN)
- 客户端通过connect连接服务器,客户端TCP将发送一个SYN包,告诉服务器客户端将在待建立连接发送数据的初始序列号。(客户端:CLOSED->SYN_SENT)
- 服务器端必须ACK客户端SYN,同时发送一个SYN,告诉客户端,服务器将在待建立连接发送数据的初始序列号。(服务器:SYN_RCVD)
- 客户端必须ACK服务器SYN。(客户端:SYN_SENT->ESTABLISHED)
- 服务器接收到客户端ACK。(服务器:SYN_RECV->ESTABLISHED)
下图给出三次握手对应的状态转移图:
2. 建立连接(同时打开simultaneous open)
参考《TCP/IP详解》卷一第18章18.8节。这种情况发生在两端几乎同时发送SYN并且这两个SYN在网络中交错的情形。这种情况可能发生,但是非常罕见。
例如,主机A的应用程序使用本地端口7777,并与主机B的端口8888执行主动打开。主机B的应用程序使用本地端口8888,并与主机A的端口7777执行主动打开。
下图给出同时打开过程:
下图给出同时打开的状态转移图:
说明:从目前个人经验来看,这种场景没有遇到过,但这是完整理解TCP状态转移必须的一部分。但《TCP/IP详解》卷一第18章18.8节中支出,许多伯克利版的TCP实现都不能正确地支持打开。
3. 建立连接失败(1)
考虑场景:客户端尚未接收到服务器ACK+SYN,异常退出(崩溃退出)。这时,当客户端接收到服务器的ACK+SYN时,客户端回复RST(reset)。此时服务器处于SYN_RCVD状态,当接收到客户端RST时,则从SYN_RCVD转移到LISTEN状态。
具体过程:
- 服务器准备好接受外来连接,通常通过socket、bind和listen完成。(服务器:CLOSED->LISTEN)
- 客户端通过connect连接服务器,客户端TCP将发送一个SYN包,告诉服务器,客户端将在待建立连接发送数据的初始序列号。然后客户端异常退出。(客户端:CLOSED->SYN_SENT,然后突然crash,则退出SYN_SENT)
- 服务器端ACK客户端SYN,同时发送一个SYN,告诉客户端,服务器将在待建立连接发送数据的初始序列号。(服务器:SYN_RCVD)
- 客户端找不到服务器ACK+SYN对应的SYN_SENT状态的socket,则响应RST。(服务器:SYN_RCVD->LISTEN)
下图给出建立连接失败的状态转移图:
4. 建立连接失败(2)
考虑场景1:服务器的进程异常退出,客户端不知道。那么客户端发送SYN后,服务器端响应RST,则客户端建立连接失败。
考虑场景2:服务器机器关闭,导致服务器IP不可达。那么客户端发送SYN后,超时重发,超过重试次数,最终TIMEOUT,则客户端建立连接失败。
具体过程:
- 假设服务器进程退出。(服务器:LISTEN->CLOSED)
- 客户端通过connect连接服务器,客户端TCP将发送一个SYN包,告诉服务器,客户将在待建立连接发送数据的初始序列号。(客户端:CLOSED->SYN_SENT)
- 服务器端收到客户端SYN,响应RST(服务器:CLOSED)
- 客户收到RST。(客户端:SYN_SENT->CLOSED)
下图给出建立连接失败的状态转移图:
5. 断开连接(四次挥手)
- 主动关闭(active close):某个应用程序首先调用close,发送一个FIN包。
- 被动关闭(passive close):接收到FIN的对端执行被动关闭。
下图给出客户端与服务器的四次挥手过程:
- 某个应用程序首先调用close,该端发送一个FIN包,表示数据发送完毕,该应用程序再无更多数据发送给对端。(例如HTTP服务器发送Reponse数据给client后,再无多余数据发送,则Server可以执行主动关闭)(主动端:ESTABLISHED->FIN_WAIT_1)
- 接收到FIN的对端执行被动关闭。首先ACK这个收到的FIN包。该FIN包的接收也作为一个文件结束符(EOF)传递给应用程序(放在已排队等候该应用进程接收的任何其他数据之后),因为FIN包意味着接收端应用进程在相应的连接上再无额外数据可接收。(被动端:ESTABLISHED->CLOSE_WAIT,主动端:FIN_WAIT_1->FIN_WAIT_2)
- 一段时间后,接收到这个EOF的应用进程将调用close关闭socket。这导致它的TCP也发送一个FIN包。(被动端:CLOSE_WAIT->LAST_WAIT)
- 接收这个最终FIN的执行主动关闭的那一端ACK这个FIN。(被动端:LAST_WAIT->CLOSED,主动端:FIN_WAIT_2->TIME_WAIT(2MSL之后,TIME_WAIT->CLOSED))
下图给出四次挥手的状态转移图:
6. 断开连接(同时关闭simultaneous close)
参考《TCP/IP详解》卷一第18章18.9节。我们在前面讨论了一方(通常但不总是客户方)发送第一个FIN执行主动关闭。双方都执行主动关闭也是可能的,TCP协议也允许这样的同时关闭(simultaneous close)。
下图给出同时关闭过程:
下图给出同时关闭的状态转移图:
7. 断开连接(在FIN_WAIT_1状态中,接收FIN+ACK)
考虑场景:被动关闭端收到FIN包后,直接发送FIN+ACK,则主动关闭方则从FIN_WAIT_1跳过FIN_WAIT_2,直接进入TIME_WAIT。
给出具体流程:
- 某个应用程序首先调用close,该端发送一个FIN包,表示数据发送完毕,该应用程序再无更多数据发送给对端。(例如HTTP服务器发送Reponse数据给client后,再无多余数据发送,则Server可以执行主动关闭)(主动端:ESTABLISHED->FIN_WAIT_1)
- 接受到FIN的对端执行被动关闭。收到FIN包之后,被动端调用close关闭socket,则FIN+ACK同时发给主动端。(被动端:ESTABLISHED->CLOSE_WAIT->LAST_ACK,主动端:FIN_WAIT_1->TIME_WAIT)
- 接收这个最终FIN的执行主动关闭的那一端ACK这个FIN。(被动端:LAST_WAIT->CLOSED,主动端:FIN_WAIT_1->TIME_WAIT(2MSL之后,TIME_WAIT->CLOSED))
下图给出同时关闭的状态转移图:
参考:
- 中文版《UNIX网络编程》第一卷第2章
- 中文版《TCP/IP详解》卷一第18章
错误说明:
- 中文版《UNIX网络编程》第一卷(第三版)(第一次印刷版)图2.4有个错误,服务器从LISTEN转移到SYN_RCVD时,条件应该是“接收:SYN;发送:SYN,ACK”,而不是“接收:RST;发送:SYN,ACK”。这一点可以从英文原本的配图看到。(注:2015年8月第二次印刷已经修订这个错误)
- 我也认为,书中的TCP状态转移图中,SYN_RCVD转移到LISTEN的条件应该是服务器状态,而非客户端状态。
关于作者:
限于本人对某些技术点的理解程度(虽然也查了很多资料),可能某些地方表达的不太准确,敬请指教,联系方式为pengfeicui@yeah.net。
读懂TCP状态转移的更多相关文章
- 使用 tcpdump 抓包分析 TCP 三次握手、四次挥手与 TCP 状态转移
目录 文章目录 目录 前文列表 TCP 协议 图示三次握手与四次挥手 抓包结果 抓包分析 TCP 三次握手 数据传输 四次挥手 TCP 端口状态转移 状态转移 前文列表 <常用 tcpdump ...
- 一篇带你读懂TCP之“滑动窗口”协议
前言 你现在的努力,是为了以后有更多的选择. 在上一篇文章通过"表白"方式,让我们快速了解网络七层协议了解了网络七层协议. 接下来我们要把重心放在网络传输的可靠性上面.一起来看TC ...
- 五分钟带你读懂 TCP全连接队列(图文并茂)
爱生活,爱编码,微信搜一搜[架构技术专栏]关注这个喜欢分享的地方. 本文 架构技术专栏 已收录,有各种视频.资料以及技术文章. 一.问题 今天有个小伙伴跑过来告诉我有个奇怪的问题需要协助下,问题确实也 ...
- 一片非常有趣的文章 三分钟读懂TT猫分布式、微服务和集群之路
原文http://www.cnblogs.com/smallSevens/p/7501932.html#3782600 三分钟读懂TT猫分布式.微服务和集群之路 针对新手入门的普及,有过大型网站技 ...
- 【一起来烧脑】读懂HTTP知识体系
背景 读懂HTTP很重要,参加过面试的小伙伴都很清楚,无论是技术面试面试题出得怎样,都有机会让你讲解一下HTTP,大部分都会问一下. 面试官:考考你网络协议的知识,TCP协议和UDP协议的区别,HTT ...
- 一文读懂HTTP/2及HTTP/3特性
摘要: 学习 HTTP/2 与 HTTP/3. 前言 HTTP/2 相比于 HTTP/1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何 ...
- 从HTTP/0.9到HTTP/2:一文读懂HTTP协议的历史演变和设计思路
本文原作者阮一峰,作者博客:ruanyifeng.com. 1.引言 HTTP 协议是最重要的互联网基础协议之一,它从最初的仅为浏览网页的目的进化到现在,已经是短连接通信的事实工业标准,最新版本 HT ...
- 一文读懂 深度强化学习算法 A3C (Actor-Critic Algorithm)
一文读懂 深度强化学习算法 A3C (Actor-Critic Algorithm) 2017-12-25 16:29:19 对于 A3C 算法感觉自己总是一知半解,现将其梳理一下,记录在此,也 ...
- 一篇文章,读懂Netty的高性能架构之道
一篇文章,读懂Netty的高性能架构之道 Netty是由JBOSS提供的一个java开源框架,是一个高性能.异步事件驱动的NIO框架,它提供了对TCP.UDP和文件传输的支持,作为一个异步NIO框架, ...
随机推荐
- Thirft框架介绍
1.前言 Thrift是一个跨语言的服务部署框架,最初由Facebook于2007年开发,2008年进入Apache开源项目.Thrift通过一个中间语言(IDL, 接口定义语言)来定义RPC的接口和 ...
- 2017-6-6&6-8/大型网站架构总结
一.WikiPedia(维基百科) WikiPedia是非盈利网站,因此尽可能地使用免费的软件和廉价的服务器.截止到2012年,这个只有区区数百台服务器和十余个技术人员开发.维护的网站,成为流量全球排 ...
- 水题系列一:Circle
问题描述:Circle 小明在玩游戏,他正在玩一个套圈圈的游戏.他手里有 L 种固定半径的圆圈,每一种圆 圈都有其固定的数量.他要把这些圆圈套进 N 个圆形槽中的一个.这些圆形槽都有一个最 小半径和最 ...
- MySQL查询性能调优化
一.索引的概念 索引:类似于字典的目录,设置索引可以 加速数据查找,对数据进行约束: 二.索引类型: 主键索引:保证数据唯一性,不能重复+不能为空 普通索引:加速数据查找 唯一索引:加速查找+不能重复 ...
- Linux使用ntpdate和ntpd进行时间同步
生产环境关联主机间常要求时间一致,若有NTP时间同步服务器,可配置各主机与时间同步服务器同步时间. 1.使用ntpdate进行时间同步 安装ntp客户端: yum install ntpdate 同步 ...
- 【CSV文件】CSV文件内容读取
CSV(逗号分隔值文件格式) 逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本).纯文本 ...
- Win10系列:JavaScript多媒体
在应用程序的日常使用中,经常会使用多媒体播放器来播放多媒体文件,包括视频.音频等,因此对于开发者来说,学习多媒体播放技术对开发应用是很有帮助的.本小节主要介绍如何使用HTML5和JavaScrip实现 ...
- jdk重装后com.sun.tools.javac.Main is not on the classpath的问题 .
在重装了JDk之后,在编译工程的时候出现如下错误: com.sun.tools.javac.Main is not on the classpath.Perhaps JAVA_HOME does no ...
- 前端小菜鸡使用Vue+Element笔记(一)
关于使用Vue+Element的项目简介~ 最近因为项目组缺前端人员,所以自己现学现做页面,先把前后台功能调通 觉得前端可真的是不容易呀哎呀~ 首先记录一下相关的Vue入门的教程: vue环境搭建示例 ...
- 用flask Flask-RESTful,实现RESTful API
简介: 自从Roy Fielding博士在2000年他的博士论文中提出REST(Representational State Transfer)风格的软件架构模式后,REST就基本上迅速取代了复杂而笨 ...