1、TCP建立连接需要3次握手

首先,client端会发出一个SYN,server收到之后,会回复ACK,并同时发出一个SYN,client收到后连接就可以建立。三次握手保证了双发通讯正常。

这就和我们打电话一样:

张三:在吗?(向李四发出信息,等待李四响应)

李四:在。   (李四收到信息后,回复张三;到这里只能说明张三的消息,李四可以收到。所以要保证通讯畅通,李四需要向张三发出信息,等待张三回复。)

张三:收到。 (这里张三回复收到,则意味着李四发出的信息,张三也可以收到。  这样才建立一个可靠的连接)

2、TCP连接断开需要四次挥手

图中的client、service只是为了描述一个连接关闭流程,实际上不管客户端还是服务端都可以主动关闭连接。

为什么需要四次挥手呢?

TCP是全双工通讯,当收到对方发来的FIN包,只意味着对方可以关闭连接了,自己可能还有数据要发送。所以FIN需要单独在发一次。

3、TCP状态转移图

Closed: 是初始状态

Listen:表示服务器的某个socket处于监听状态,可以接受连接

SYN_rcvd:表示收到了SYN报文,这是服务器的一个中间态、很短暂。

SYN_send:客户端发送SYN报文后,会变成这个状态,与SYN_rcvd对应。

Established:表明连接已经建立,这可以说是一个稳定态,使用netstat 可以观察到双方建立的连接。

Close_wait:正常来说,这应该也是一个中间态,它代表着四次挥手中收到对方发来的FIN,回复了ack,在向对方发送FIN之前,就是这个状态。  (很多时候我们会发现程序出问题时出现很多close_wait,这个状态出现就是由于在收到对方关闭连接后,自身未发出FIN包导致。大量的close_wait状态会导致HTTP请求无法响应,你的程序会宕掉,你需要检查一下你的代码了)

LAST_ack:这个状态是被动关闭的一方发送FIN后,等待四次握手中最后一个Ack(也就是主动关闭方发来的ack)之前的状态。

FIN_wait_1:这也是个中间态,基本看不到。当主动关闭方向对方发送FIN报文后,主动方便是FIN_wait_1状态。

FIN_wait_2:接着上面FIN_wait1说的,在主动关闭连接的一方发送FIN报文后,自身成为FIN_wait1,当收到对方的ACK时,变为FIN_wait_2。

TIME_wait:接受到对方的FIN,并回复了ack。此时等待2MSL(MSL为最长报文存活时间,可在操作系统中配置),连接即可关闭。这是一个正常态,存在请求时netstat即可看到。

closing:比较特殊,可能是双发同时关闭连接时会出现的状态。图中可以看到,之后会变为Time_wait,2MSL后连接随之关闭。

4、来看一个HTTP请求的抓包

浮生若梦,忙里偷闲, 使用tcpdump抓包来看看一次HTTP请求TCP连接的建立断开。

一个正常的HTTP请求抓包

tcpdump -i lo -n port 8080 -S#tcpdump用法自己百度一下

我们触发一次

15:58:19.333425 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [S], seq 4076194383, win 43690, options [mss 65495,sackOK,TS val 1559458260 ecr 0,nop,wscale 7], length 0
15:58:19.333436 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [S.], seq 2069165181, ack 4076194384, win 43690, options [mss 65495,sackOK,TS val 1559458260 ecr 1559458260,nop,wscale 7], length 0
15:58:19.333448 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [.], ack 2069165182, win 342, options [nop,nop,TS val 1559458260 ecr 1559458260], length 0
15:58:19.333548 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [P.], seq 4076194384:4076195143, ack 2069165182, win 342, options [nop,nop,TS val 1559458260 ecr 1559458260], length 759
15:58:19.333562 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [.], ack 4076195143, win 354, options [nop,nop,TS val 1559458260 ecr 1559458260], length 0
15:58:19.353547 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [P.], seq 2069165182:2069165253, ack 4076195143, win 354, options [nop,nop,TS val 1559458280 ecr 1559458260], length 71
15:58:19.353557 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [.], ack 2069165253, win 342, options [nop,nop,TS val 1559458280 ecr 1559458280], length 0
15:58:19.353835 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [P.], seq 2069165253:2069165340, ack 4076195143, win 354, options [nop,nop,TS val 1559458281 ecr 1559458280], length 87
15:58:19.353843 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [.], ack 2069165340, win 342, options [nop,nop,TS val 1559458281 ecr 1559458281], length 0
15:58:19.354004 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [F.], seq 4076195143, ack 2069165340, win 342, options [nop,nop,TS val 1559458281 ecr 1559458281], length 0
15:58:19.354228 IP 127.0.0.1.8080 > 127.0.0.1.49455: Flags [F.], seq 2069165340, ack 4076195144, win 354, options [nop,nop,TS val 1559458281 ecr 1559458281], length 0
15:58:19.354239 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [.], ack 2069165341, win 342, options [nop,nop,TS val 1559458281 ecr 1559458281], length 0

TCP Flag包含8个比特位,分别是:CWR,ECE,URG,ACK,PSH,RST,SYN,FIN。

SYN:在建立连接时标记,三次握手中syn就是这个.

ACK:用来告诉对方数据包已收到,返回的数据中会将顺序号+1.

PSH:(push)表示需要将收到的包交给应用层.

FIN:表示自己已经没有数据要发送了,准备关闭连接.

看一下抓包数据,前三个包,就是三次握手建立连接的过程:第一个包Flags[S] 代表客户端发送的SYN,第二个包Flags[S.]代表服务端返回的ack和向客户端发出的SYN,第三个包Flags[.]是客户端回复的ack.至此三次握手完成,连接建立。

中间的包是请求和响应,来看最后三个包.就是四次挥手来关闭连接。

Flags[F.]代表主动关闭的一方没有数据发送了,向对方发送了FIN来关闭连接。倒数第二个包Flags[F.]表示被动一方回复ack,并且发出FIN表示也要关闭连接了(这里FIN与ack一起发可以理解为TCP自身的优化机制),最后一个包F[.]主动关闭一方回复ack,连接关闭。

再来分析一下Flags[P]包中数据的含义:

15:58:19.333548 IP 127.0.0.1.49455 > 127.0.0.1.8080: Flags [P.], seq 4076194384:4076195143, ack 2069165182, win 342, options [nop,nop,TS val 1559458260 ecr 1559458260], length 759

15:58:19.333548: 这个一看就是收到包时间了

127.0.0.1.49455 :是发送方的IP和端口

127.0.0.1.8080 :是服务端的IP和端口

Flags [P.]  :P代表PSH标志位,表明改包需要推送到应用层,至于这里的.可以理解为一个占位符,不考虑。

seq 4076194384:4076195143 : tcp报文的seq号, 4076194384是起始值,4076195143是结束值, 4076195143 -4076194384是发送报文长度。

ack 2069165182 :tcp报文的ack号, ack 2069165182 表明标号2069165181报文已收到。下一个接收的seq号会从2069165182 开始。

win 342 :表示tcp报文发送方作为接收方还可以接受的字节数,大于这个数,可能就处理不了了。

options [nop,nop,TS val 1559458260 ecr 1559458260]:这里nop是 no operation,可以不考虑;TS val 1559458260是报文的时间戳,这个值与系统时间无关,用来做seq值越界重新从0开始计算时,确认包顺序;ecr 1559458260 这个值用来计算RTT

length 759:这个值表示应用层传来数据的大小(不包括TCP header),与上面seq 4076194384:4076195143相减对应。

最后附上一个带完整数据的请求抓包(与上面抓包对应)

tcpdump -i lo -n port 8080 -SAl
15:56:45.608564 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [S], seq 3763193645, win 43690, options [mss 65495,sackOK,TS val 1559364535 ecr 0,nop,wscale 7], length 0
..............E..<..@.@.x............-.M.-.........0.........
\...........
15:56:45.608581 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [S.], seq 3127397756, ack 3763193646, win 43690, options [mss 65495,sackOK,TS val 1559364535 ecr 1559364535,nop,wscale 7], length 0
..............E..<..@.@.<..........-...hM|.M.......0.........
\...\.......
15:56:45.608595 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [.], ack 3127397757, win 342, options [nop,nop,TS val 1559364535 ecr 1559364535], length 0
..............E..4..@.@.x&...........-.M...hM}...V.(.....
\...\...
15:56:45.608705 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [P.], seq 3763193646:3763194405, ack 3127397757, win 342, options [nop,nop,TS val 1559364535 ecr 1559364535], length 759
..............E..+..@.@.u............-.M...hM}...V. .....
\...\...GET /rest/ee7d191e/get?page=1&start=0&limit=15 HTTP/1.1
x-real-ip: 172.16.70.33
remote-host: 172.16.70.33
x-forwarded-for: 172.16.70.33
user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
x-requested-with: XMLHttpRequest
accept: */*
referer: http://172.16.70.22/ui
accept-encoding: gzip, deflate
accept-language: zh-CN,zh;q=0.9
cookie: connect.sid=s%3AYbFf2HMeIBrYNw-GY7PH86N0uqRa4Uda.gCS1W0CXVkGAoJg52r7vBWeYvN0615vMSC%2F6aUuro0o
connection: close
user: administrator
sid: YbFf2HMeIBrYNw-GY7PH860uqRa4Uda
ip_address: 172.16.70.33
content-length: 2
Accept-Charset: utf-8
Host: localhost:8080{}
15:56:45.608715 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [.], ack 3763194405, win 354, options [nop,nop,TS val 1559364535 ecr 1559364535], length 0
..............E..4N.@.@............-...hM}.M.%...b.(.....
\...\...
15:56:45.718585 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [P.], seq 3127397757:3127397828, ack 3763194405, win 354, options [nop,nop,TS val 1559364645 ecr 1559364535], length 71
..............E..{N.@.@............-...hM}.M.%...b.o.....
\..%\...HTTP/1.1 200 OK
Content-Type: application/json
content-length: 8715:56:45.718595 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [.], ack 3127397828, win 342, options [nop,nop,TS val 1559364645 ecr 1559364645], length 0
..............E..4..@.@.x$...........-.M.%.hM....V.(.....
\..%\..%
15:56:45.718887 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [P.], seq 3127397828:3127397915, ack 3763194405, win 354, options [nop,nop,TS val 1559364646 ecr 1559364645], length 87
..............E...N.@.@............-...hM..M.%...b.......
\..&\..%{"result":{"errorDesc":"Successfully","errorCode":0},"list":[],"totalCount":0}
15:56:45.718897 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [.], ack 3127397915, win 342, options [nop,nop,TS val 1559364646 ecr 1559364646], length 0
..............E..4..@.@.x#...........-.M.%.hN....V.(.....
\..&\..&
15:56:45.719429 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [F.], seq 3763194405, ack 3127397915, win 342, options [nop,nop,TS val 1559364646 ecr 1559364646], length 0
..............E..4..@.@.x"...........-.M.%.hN....V.(.....
\..&\..&
15:56:45.719717 IP 127.0.0.1.8080 > 127.0.0.1.49075: Flags [F.], seq 3127397915, ack 3763194406, win 354, options [nop,nop,TS val 1559364646 ecr 1559364646], length 0
..............E..4N.@.@............-...hN..M.&...b.(.....
\..&\..&
15:56:45.719732 IP 127.0.0.1.49075 > 127.0.0.1.8080: Flags [.], ack 3127397916, win 342, options [nop,nop,TS val 1559364646 ecr 1559364646], length 0
..............E..4..@.@.x!...........-.M.&.hN....V.(.....
\..&\..&

TCP状态转换图——简述11个状态相关推荐

  1. TCP协议连接的11种状态浅谈

    了解TCP的协议可以在很大程度上帮助我们分析服务器当前的TCP连接状态,同时也是排查一些网络故障的基础,首先来看一下TCP协议的三次握手与四次断开. TCP协议三次握手   1.客户端首先发起连接,也 ...

  2. 线程状态转换图及其5种状态切换

    线程的状态切换图: 线程变化的5状态转换: 新建状态(New):新创建了一个线程对象. 就绪状态(Runable)/可运行状态:线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位 ...

  3. TCP面试常见题:time_wait状态产生的原因,危害,如何避免

    http://blog.csdn.net/u013616945/article/details/77510925 MSL(Maximum Segment Lifetime)最大报文生存时间       ...

  4. [编译原理课设] 自动机的状态转换图表示

    课程设计的要求 要求设计一个具有绘图功能的程序,可以手工以状态转换图的方式绘制自动机: 图形化的自动机可以保存,读取: 根据状态转换图得出自动机的状态转换矩阵: 根据状态转换矩阵,自动绘制出状态转换图 ...

  5. 请使用命令行统计各tcp状态的数量_TCP 连接状态及相关命令学习

    在平时的开发工作中,我们都使用被封装完好的 TCP/HTTP 库去完成需求开发,很少关心底层 TCP 的连接状态,但是一旦遇到较难定位的线上事故,往往都是因为 TCP 连接参数或者使用姿势不对导致的, ...

  6. 编译原理记录2——状态转换图 有穷自动机

    文章目录 状态转换图 状态转换图 有穷自动机 NFA DFA 状态转换图 状态转换图 状态:表示在识别词素的过程中可能出现的情况 状态看作是已处理部分的总结 某些状态为接受状态或最终状态,表明已找到词 ...

  7. 【Unix 网络编程】TCP状态转换图详解

    TCP协议的三路握手和四次挥手.如下图所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手).数据传输.断开TCP连接通道(四次挥手). 这里进一步探究TCP三路握手和四次挥手过程中的状态变 ...

  8. 实时监测tcp链接状态_终于搞懂了 TCP 的 11 种状态,太不容易了…

    后台回复"666",获取新资料 本来想写运维过程中,nginx 服务器中 time_wait 的相关测试及解决方法的,然后发现TCP 的状态需要先铺垫一下,于是就整理了这篇文章. ...

  9. TCP/IP / 四次挥手之状态转换图、过程说明和原因

    一.状态转换图 二.过程说明 1.Client:我要断开连接啦! 2.Server:好的!稍等,我这还有一些数据需要发送给你,等完事我再断开连接哈. --(server 向 client 发送数据) ...

最新文章

  1. 师生对话:我们都曾是爱学习的孩子
  2. 另一个小程序 返回的支付结果如何得到_手把手教你测微信小程序
  3. 小龙虾上天了!口碑APP推出飞机上扫码点餐服务
  4. 华为mate40计算机,原来拍摄还能这么玩?华为Mate40 Pro连接电脑+耳机,Vlog输出分分钟...
  5. vue 开发一个按钮组件
  6. 快速了解 ASP.NET Core Blazor
  7. Django学习笔记《一》初始化pycharm和mysql数据库及相关环境
  8. kali2 安装docker_kali linux 安装docker
  9. SRM 567 div2
  10. 分布式一致性算法-paxos详解与分析
  11. RxJAVA notes
  12. python 视频 添加字幕_爱剪辑加字幕之经验及Python程序批量加字幕
  13. 中国农业大学计算机专硕2019分数线,2019中国农业大学生物学院硕士生复试分数线(北京)...
  14. invalid index of a 0-dim tensor
  15. Neo4j使用记录--APOC和GDS的安装【实践】
  16. Linux centos7 mysql 配置支持emoji表情包,笔记
  17. nuc7 android tv,NUC7PJYH HDMI在特定显示屏上出现问题
  18. android recovery分区内刷镜像,Android手机Recovery模式取证方法研究.pdf
  19. 用户态协议栈tcp/ip设计
  20. 如何直接打印int[]数组

热门文章

  1. 基于JAVA动漫网站和特效处理系统(Springboot框架+AI人工智能) 开题报告
  2. Maven学习九:依赖-dependency
  3. 点击网页中正常链接结果跳转到天猫淘宝的页面
  4. 卡罗拉 (COROLLA) - 开启引擎盖
  5. 实现AI角色的自主移动——操控行为
  6. NOIP2018 模拟测试 day1 战棋游戏
  7. [Linux系统编程]_文件编程(一)
  8. 用python来打印数字金字塔
  9. 微擎在平台入口不显示安装的模块_【微擎系统】2.0.8更新说明
  10. 图像所征服你的七种武器