tcp 三次握手和四次挥手
一。协议格式
以太网帧格式
目的地址. 下一跳的mac地址,每一跳都会变
源地址. 当前路由器的mac地址,每一跳都会改变
PAD 为填充字节,28+18=46,满足数据的最小长度 46
CRC 为校验帧数据是否损坏,比如奇偶校验等
arp协议格式
前三个段对应以太网的前三个段
硬件类型 硬件地址有很多种,以太网时为 0001
协议类型 协议类型,IPv4 为 0800
6和7 硬件地址长度和协议地址长度,分别为 mac 地址 和 IP 地址,即 6 和 4
op 操作类型,1为 arp 请求,2为 arp 应答, 3为 RARP 请求,4为 RARP 应答
9 和 2 相同
IP 协议格式
版本. 4为 ipv4 和 6为 ipv6
首部长度 记录头部的长度,单位为32字长(即4字节),一般为图上的 20 字节
服务类型 一般不使用
总长度. 整个IP段的长度
标识标志偏移。 主要用在分片传输
TTL. 该IP包可经过多少跳,即多少个路由器,避免循环,每经过一跳该值减一
协议 ICMP:1,TCP:6,UDP:17等
首部校验和。 校验头部,校验错误直接丢弃该包
源IP地址 最开始发送端的IP地址,传输过程中不变
目的IP地址. 最终要发送到的目的IP地址,传输过程中不变
具体查看 https://baike.baidu.com/item/IP数据报/1581132?fr=aladdin
tcp协议格式
端口号 标识进程,ip确定是哪台主机,再加上端口就确定某台主机的进程
顺序号 tcp传输时的 序列号 seq
确认号 tcp传输时的 确认号 ack,控制位的 ack 为 1 时有效
头部长度 记录头部的长度,单位为32字长(即4字节),一般为图上的 20 字节
控制位
urg 为 1 时 头部的紧急指针有效
ack 为 1 时 头部的确认号有效
psh push 标志,为 1 时,应尽快将报文给应用程序,而不是在缓冲区排队
pst 为 1 时,重置连接,用于重置错误的链接,或者拒接非法连接
syn 用于建立连接,即 tcp 连接请求时的 syn
fin finish 标志,用于关闭连接,本方不再发送连接
窗口大小 滑动窗口,发送和接收的缓存大小,用于流量控制
校验和 校验头部和数据,一般为奇偶校验
紧急指针 urg 为 1 时有效,和顺序号相加来表示最后一个紧急数据的序号
udp 协议格式
二。OSI七层模型
应用层 单位 APDU , 提供应用能访问 OSI 的环境,如 FTP,HTTP,DNS
表示层 单位 PPUD ,对数据 翻译,加密,压缩等, 如 JPEG,ASII ,即电脑直接表示给我门看的图片,压缩包等这些
会话层 单位 SPUD ,建立,管理,终止会话,如 RPC,NFS
传输层 单位 报文(对应上面的tcp和udp),确定 端到端 的报文传递, 如 TCP,UDP
网络层 单位 包(对应上面的IP包协议格式), 确定 网际互联 ,如 IP,ARP,ICMP(通常用的 ping 命令)
数据链路层 单位 帧(对应上面的以太网帧格式),确定 点到点 到传递,如 MAC,VLAN,PPP
物理层 单位 比特(bit) ,确定电气及机械规范,如 RJ45
传输层及以下由内核操作,即打包拆包都是由内核完成。
TCP/IP 四层模型
网络接口层 MAC,VLAN
网络层 IP,ARP,ICMP
传输层 TCP,UDP
应用层 HTTP,DNS,SMTP
三。arp 请求流程
进入 511 的容器,IP为 172.17.0.2
监听 172.17.0.3 主机的数据包
打开另一个终端,同样进入 511 容器,查看 arp ,记录了网关的 mac 地址
接着进入 3f2 的容器, IP为 172.17.0.3
监听 172.17.0.2 主机的数据包
在 3f2 容器里运行上一节的简单 socket ,https://www.cnblogs.com/GH-123/p/12873578.html
在 511 容器访问该服务
首先查看 511 的监听
15:46:17.617782 ARP, Request who-has 172.17.0.3 tell 51131c93a7f8, length 28 0x0000: ffff ffff ffff 0242 ac11 0002 0806 0001 .......B........ 0x0010: 0800 0604 0001 0242 ac11 0002 ac11 0002 .......B........ 0x0020: 0000 0000 0000 ac11 0003 ..........
因为 511 要去访问 172.17.0.3 ,但不知道是哪台主机,所以在局域网内广播 谁是172.17.0.3告诉511 包格式如下(对照上面图的协议格式)
ffff ffff ffff 6字节目的mac地址,当前是不知道的,所以没有 0242 ac11 0002 6字节源mac地址,就是本机511的地址 0806 arp包 0001 硬件类型为 以太网 0800 协议类型为 IPv4 06 硬件地址长度,6字节mac的长度 04 协议地址长度,4字节IPv4的长度 0001 操作类型,arp 请求 0242 ac11 0002 和源mac地址一样 ac11 0002 发送端IP,即本机511的IP地址,16进制转换成10进制即172.17.0.2 0000 0000 0000 和目的mac地址一样 ac11 0003 目的IP地址,16进制转10进制即 172.17.0.3
接着查看 3f2 的监听
15:46:17.617836 ARP, Request who-has 3f27cc192e98 tell 172.17.0.2, length 28 0x0000: ffff ffff ffff 0242 ac11 0002 0806 0001 .......B........ 0x0010: 0800 0604 0001 0242 ac11 0002 ac11 0002 .......B........ 0x0020: 0000 0000 0000 ac11 0003
收到了一条 511 发送的 arp 请求包,发现自己就是 3f2(即 172.17.0.3),所以发送 arp 应答包给 511 , 172.17.0.3 的 mac 地址是 02:42:ac:11:00:03
15:46:17.617845 ARP, Reply 3f27cc192e98 is-at 02:42:ac:11:00:03 (oui Unknown), length 28 0x0000: 0242 ac11 0002 0242 ac11 0003 0806 0001 .B.....B........ 0x0010: 0800 0604 0002 0242 ac11 0003 ac11 0003 .......B........ 0x0020: 0242 ac11 0002 ac11 0002 .B........
这个包的格式和刚刚的请求包差不多,对号入座即可,接着查看 511 的监听收到该应答包
15:46:17.617849 ARP, Reply 172.17.0.3 is-at 02:42:ac:11:00:03 (oui Unknown), length 28 0x0000: 0242 ac11 0002 0242 ac11 0003 0806 0001 .B.....B........ 0x0010: 0800 0604 0002 0242 ac11 0003 ac11 0003 .......B........ 0x0020: 0242 ac11 0002 ac11 0002 .B........
此刻 511 和 3f2 就互相知道了对方(缓存了arp),接下来就可以传输数据了
[root@51131c93a7f8 /]# arp Address HWtype HWaddress Flags Mask Iface 172.17.0.3 ether 02:42:ac:11:00:03 C eth0 gateway ether 02:42:b5:13:63:ed C eth0 [root@51131c93a7f8 /]#
[root@3f27cc192e98 ~]# arp Address HWtype HWaddress Flags Mask Iface gateway ether 02:42:b5:13:63:ed C eth0 172.17.0.2 ether 02:42:ac:11:00:02 C eth0 [root@3f27cc192e98 ~]#
四。tcp三次握手建立连接
在完成上面的 arp 请求后就会进入三次握手,syn 为1 发起建立连接请求
对照协议格式分析该包如下
06:24:32.720484 IP 51131c93a7f8.36922 > 172.17.0.3.ircu-2: Flags [S], seq 3179747642, win 29200, options [mss 1460,sackOK,TS val 7033 ecr 0,nop,wscale 7], length 0 0x0000: 0242 ac11 0003 0242 ac11 0002 0800 4500 .B.....B......E. 0x0010: 003c 0243 4000 4006 e051 ac11 0002 ac11 .<.C@.@..Q...... 0x0020: 0003 903a 1a0a bd87 193a 0000 0000 a002 ...:.....:...... 0x0030: 7210 5856 0000 0204 05b4 0402 080a 0000 r.XV............ 0x0040: 1b79 0000 0000 0103 0307 .y........
0242 ac11 0003 目的 mac 地址 0242 ac11 0002 源 mac 地址 0800 IP数据包 上面是以太网帧格式,下面为IP数据包 4 IPv4 5 首部长度, 4字节 * 5 = 20 字节 00 服务类型,不使用 003c 总长度, 60 字节 0243 分片标识,相同的数据包被分片后该标识相同,重装数据 4000 不分片 40 生存时间,64跳 06 协议类型,6 为 tcp e051 首部校验和 ac11 0002 源IP地址,172.17.0.2 ac11 0003 目的IP地址 172.17.0.3 上面是IP数据包,下面是 tcp 报文 903a 源端口号,即 36922 1a0a 目标端口,即访问的 6666 端口 bd87 193a 序列编号,即 seq 3179747642 0000 0000 确认序号,即 ack a 头部长度,即 4字节 * 10 = 40 字节 002 控制位,即 syn 为 1 ,建立连接 7210 窗口大小 ...略
511 向 3f2 发送了请求建立连接的报文, 3f2 收到该报文 ,查看 3f2 的监听
06:24:32.720515 IP 172.17.0.2.36922 > 3f27cc192e98.ircu-2: Flags [S], seq 3179747642, win 29200, options [mss 1460,sackOK,TS val 7033 ecr 0,nop,wscale 7], length 0 0x0000: 0242 ac11 0003 0242 ac11 0002 0800 4500 .B.....B......E. 0x0010: 003c 0243 4000 4006 e051 ac11 0002 ac11 .<.C@.@..Q...... 0x0020: 0003 903a 1a0a bd87 193a 0000 0000 a002 ...:.....:...... 0x0030: 7210 5856 0000 0204 05b4 0402 080a 0000 r.XV............ 0x0040: 1b79 0000 0000 0103 0307 .y........
3f2 向 511 回应该请求,确认号 ack = seq + 1 ,并同时发送 seq 和 511 的确立连接
06:24:32.720532 IP 3f27cc192e98.ircu-2 > 172.17.0.2.36922: Flags [S.], seq 1058035807, ack 3179747643, win 28960, options [mss 1460,sackOK,TS val 7033 ecr 7033,nop,wscale 7], length 0 0x0000: 0242 ac11 0002 0242 ac11 0003 0800 4500 .B.....B......E. 0x0010: 003c 0000 4000 4006 e294 ac11 0003 ac11 .<..@.@......... 0x0020: 0002 1a0a 903a 3f10 585f bd87 193b a012 .....:?.X_...;.. 0x0030: 7120 5856 0000 0204 05b4 0402 080a 0000 q.XV............ 0x0040: 1b79 0000 1b79 0103 0307 .y...y....
511 收到 3f2 的回应请求,确认 511 --到--> 3f2 的连接通信
06:24:32.720538 IP 172.17.0.3.ircu-2 > 51131c93a7f8.36922: Flags [S.], seq 1058035807, ack 3179747643, win 28960, options [mss 1460,sackOK,TS val 7033 ecr 7033,nop,wscale 7], length 0 0x0000: 0242 ac11 0002 0242 ac11 0003 0800 4500 .B.....B......E. 0x0010: 003c 0000 4000 4006 e294 ac11 0003 ac11 .<..@.@......... 0x0020: 0002 1a0a 903a 3f10 585f bd87 193b a012 .....:?.X_...;.. 0x0030: 7120 5856 0000 0204 05b4 0402 080a 0000 q.XV............ 0x0040: 1b79 0000 1b79 0103 0307 .y...y....
然后 511 同样 回应 3f2 的确认连接,确认号 ack = seq + 1
06:24:32.720550 IP 51131c93a7f8.36922 > 172.17.0.3.ircu-2: Flags [.], ack 1058035808, win 229, options [nop,nop,TS val 7033 ecr 7033], length 0 0x0000: 0242 ac11 0003 0242 ac11 0002 0800 4500 .B.....B......E. 0x0010: 0034 0244 4000 4006 e058 ac11 0002 ac11 .4.D@.@..X...... 0x0020: 0003 903a 1a0a bd87 193b 3f10 5860 8010 ...:.....;?.X`.. 0x0030: 00e5 584e 0000 0101 080a 0000 1b79 0000 ..XN.........y.. 0x0040: 1b79 .y
3f2 收到 511 的确认报文,最终建立双方通信
06:24:32.720555 IP 172.17.0.2.36922 > 3f27cc192e98.ircu-2: Flags [.], ack 1058035808, win 229, options [nop,nop,TS val 7033 ecr 7033], length 0 0x0000: 0242 ac11 0003 0242 ac11 0002 0800 4500 .B.....B......E. 0x0010: 0034 0244 4000 4006 e058 ac11 0002 ac11 .4.D@.@..X...... 0x0020: 0003 903a 1a0a bd87 193b 3f10 5860 8010 ...:.....;?.X`.. 0x0030: 00e5 584e 0000 0101 080a 0000 1b79 0000 ..XN.........y.. 0x0040: 1b79 .y
五。tcp 四次挥手断开连接
在上面四的基础上,三次握手成功后,查看 511 的连接状态为 数据传输状态 ESTABLISHED
接着看 3f2 的也是传输状态 ESTABLISHED
看 511 的监听,由 511 发起关闭请求,发送 fin 为 1 的关闭连接报文,进入 FIN_WAIT1
协议格式不再分析,上面已经分析过了,对号入座即可
14:48:12.546211 IP 51131c93a7f8.35042 > 172.17.0.3.ircu-2: Flags [F.], seq 162831567, ack 1544682494, win 229, options [nop,nop,TS val 441261 ecr 414422], length 0 0x0000: 0242 ac11 0003 0242 ac11 0002 0800 4500 .B.....B......E. 0x0010: 0034 ce1a 4000 4006 1482 ac11 0002 ac11 .4..@.@......... 0x0020: 0003 88e2 1a0a 09b4 9ccf 5c11 fbfe 8011 ..........\..... 0x0030: 00e5 584e 0000 0101 080a 0006 bbad 0006 ..XN............ 0x0040: 52d6 R.
接着看 3f2 的监听,此时 3f2 收到了 511 的关闭请求报文
14:48:12.546274 IP 172.17.0.2.35042 > 3f27cc192e98.ircu-2: Flags [F.], seq 162831567, ack 1544682494, win 229, options [nop,nop,TS val 441261 ecr 414422], length 0 0x0000: 0242 ac11 0003 0242 ac11 0002 0800 4500 .B.....B......E. 0x0010: 0034 ce1a 4000 4006 1482 ac11 0002 ac11 .4..@.@......... 0x0020: 0003 88e2 1a0a 09b4 9ccf 5c11 fbfe 8011 ..........\..... 0x0030: 00e5 584e 0000 0101 080a 0006 bbad 0006 ..XN............ 0x0040: 52d6 R.
然后 3f2 回应 511 确认关闭 报文,然后进入 关闭状态 即 CLOSE_WAIT
14:48:12.553148 IP 3f27cc192e98.ircu-2 > 172.17.0.2.35042: Flags [.], ack 162831568, win 227, options [nop,nop,TS val 441262 ecr 441261], length 0 0x0000: 0242 ac11 0002 0242 ac11 0003 0800 4500 .B.....B......E. 0x0010: 0034 a929 4000 4006 3973 ac11 0003 ac11 .4.)@.@.9s...... 0x0020: 0002 1a0a 88e2 5c11 fbfe 09b4 9cd0 8010 ......\......... 0x0030: 00e3 584e 0000 0101 080a 0006 bbae 0006 ..XN............ 0x0040: bbad ..
511 收到 3f2 的确认关闭报文后进入 半关闭状态 即 FIN_WAIT2
14:48:12.553163 IP 172.17.0.3.ircu-2 > 51131c93a7f8.35042: Flags [.], ack 162831568, win 227, options [nop,nop,TS val 441262 ecr 441261], length 0 0x0000: 0242 ac11 0002 0242 ac11 0003 0800 4500 .B.....B......E. 0x0010: 0034 a929 4000 4006 3973 ac11 0003 ac11 .4.)@.@.9s...... 0x0020: 0002 1a0a 88e2 5c11 fbfe 09b4 9cd0 8010 ......\......... 0x0030: 00e3 584e 0000 0101 080a 0006 bbae 0006 ..XN............ 0x0040: bbad ..
最后关闭 3f2 端,由 3f2 发送关闭请求,进入状态 LAST_ACK
14:48:30.448115 IP 3f27cc192e98.ircu-2 > 172.17.0.2.35042: Flags [F.], seq 1544682494, ack 162831568, win 227, options [nop,nop,TS val 443051 ecr 441261], length 0 0x0000: 0242 ac11 0002 0242 ac11 0003 0800 4500 .B.....B......E. 0x0010: 0034 a92a 4000 4006 3972 ac11 0003 ac11 .4.*@.@.9r...... 0x0020: 0002 1a0a 88e2 5c11 fbfe 09b4 9cd0 8011 ......\......... 0x0030: 00e3 584e 0000 0101 080a 0006 c2ab 0006 ..XN............ 0x0040: bbad ..
511 收到该关闭请求
14:48:30.448167 IP 172.17.0.3.ircu-2 > 51131c93a7f8.35042: Flags [F.], seq 1544682494, ack 162831568, win 227, options [nop,nop,TS val 443051 ecr 441261], length 0 0x0000: 0242 ac11 0002 0242 ac11 0003 0800 4500 .B.....B......E. 0x0010: 0034 a92a 4000 4006 3972 ac11 0003 ac11 .4.*@.@.9r...... 0x0020: 0002 1a0a 88e2 5c11 fbfe 09b4 9cd0 8011 ......\......... 0x0030: 00e3 584e 0000 0101 080a 0006 c2ab 0006 ..XN............ 0x0040: bbad ..
511 收到请求后 发送 确认关闭请求给 3f2,进入状态 TIME_WAIT ,即等待 2MLS (一般为1分钟) 的时间后关闭连接,即 CLOSED
14:48:30.448227 IP 51131c93a7f8.35042 > 172.17.0.3.ircu-2: Flags [.], ack 1544682495, win 229, options [nop,nop,TS val 443051 ecr 443051], length 0 0x0000: 0242 ac11 0003 0242 ac11 0002 0800 4500 .B.....B......E. 0x0010: 0034 0000 4000 4006 e29c ac11 0002 ac11 .4..@.@......... 0x0020: 0003 88e2 1a0a 09b4 9cd0 5c11 fbff 8010 ..........\..... 0x0030: 00e5 f6ca 0000 0101 080a 0006 c2ab 0006 ................ 0x0040: c2ab ..
3f2 收到 该确认关闭请求后,关闭连接,即 CLOSED
14:48:30.448239 IP 172.17.0.2.35042 > 3f27cc192e98.ircu-2: Flags [.], ack 1544682495, win 229, options [nop,nop,TS val 443051 ecr 443051], length 0 0x0000: 0242 ac11 0003 0242 ac11 0002 0800 4500 .B.....B......E. 0x0010: 0034 0000 4000 4006 e29c ac11 0002 ac11 .4..@.@......... 0x0020: 0003 88e2 1a0a 09b4 9cd0 5c11 fbff 8010 ..........\..... 0x0030: 00e5 f6ca 0000 0101 080a 0006 c2ab 0006 ................ 0x0040: c2ab ..
状态转换
需要结合上面的第四和第五的请求进行分析
客户端:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
服务端:
CLOSED->LISTEN->SYN-RECEIVED->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
状态解析:
LISTEN:监听TCP端口的接请求
SYN-SENT:客户端发送了 syn 建立连接请求
SYN-RECEIVED:服务端收到了 syn 建立连接请求
ESTABLISHED:三次握手成功后建立连接,可以传数据
FIN-WAIT-1:主动端发送了 fin 关闭连接请求
FIN-WAIT-2:主动端收到了 ack 确认关闭连接请求
CLOSE-WAIT:被动端回应了 ack 确认关闭连接请求
CLOSING:主动端回应了 ack 确认关闭连接请求
LAST-ACK:被动端发送了 fin 关闭连接请求
TIME-WAIT:等待 2MLS 的时间保证被动关闭端能收到最后的关闭确认请求
CLOSED:已经关闭
状态转换图
总结
1. 主动关闭端为什么要等 2MLS 的时间?
等 2MLS 的时间是为了 保证 被动关闭端 收到了 主动关闭端 的确认关闭请求,因为如果 被动关闭端 没能收到该确认关闭请求,会重发上一个的关闭请求给 主动关闭端。
2. 建立连接为什么是三次握手?而不是 二次 或者 四次?
tcp 传输是全双工的,即 双方可以同时发送和接收信息,二次握手只能确认一端的通信,如
A --请求--> B
A <--回应-- B
此时确认了 A 到 B 的通信,接着 确认 B 到 A 的通信
A <--请求-- B
A --回应--> B
此时双方互相确认了通信,需要 四次 握手才行,但 第二步和第三步可以合起来发送,即 B 在回应 A 的时候,同时发送请求给 A ,所以就只需要 三次 握手。可以看上面的第四标题,3f2 回应 511 时一起发送了建立连接请求。
3. 断开连接时为什么要四次挥手?
由第 2 问知道为什么能三次就行,因为 关闭连接的 第二步和第三步不能合在一起发送,因为主动端关闭了,被动端不一定在此刻关闭,还有可能有数据没发送完。每两次的握手只能确认一端的建立或者关闭。