• 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 问知道为什么能三次就行,因为 关闭连接的 第二步和第三步不能合在一起发送,因为主动端关闭了,被动端不一定在此刻关闭,还有可能有数据没发送完。每两次的握手只能确认一端的建立或者关闭

  • 相关阅读:
    SDSF output to PS
    3亿人出走后的中国农村,路在何方?
    oracle function
    C8051特点
    c8051单片机注意事项:
    一个因xdata声明引起的隐含错误
    宏 函数 内联函数inline
    字符串与液晶显示的一个问题
    XON/OFF
    excel之实验数据处理线性拟合
  • 原文地址:https://www.cnblogs.com/GH-123/p/12960608.html
Copyright © 2020-2023  润新知