zoukankan      html  css  js  c++  java
  • Wrieshark网络数据抓包协议分析&TCP/UDP/ICMP详解

    首先给自己提个醒

    Windows下如何运行.sh脚本

    按下win+s,搜索sh或者git,打开sh或者git bash,cd到脚本目录,通过命令运行

    sh xxx.sh [args] 

    运行的时候提示make: command not found,是因为没有make命令,参考https://blog.csdn.net/qq_35037684/article/details/106848673,通常都有c环境,直接第二步就可以了

    运行时候提示npm: command not found,是因为没有装nodejs,下载地址https://nodejs.org/zh-cn/

    背景知识

     

     

     使用过滤器

    https://blog.csdn.net/holandstone/article/details/47026213

    初学者使用wireshark时,将会得到大量的冗余信息,在几千甚至几万条记录中,以至于很难找到自己需要的部分。搞得晕头转向。过滤器会帮助我们在大量的数据中迅速找到我们需要的信息。

    表达式规则

     1. 协议过滤

    比如TCP,只显示TCP协议。

    2. IP 过滤

    比如 ip.src ==192.168.1.102 显示源地址为192.168.1.102,

    ip.dst==192.168.1.102, 目标地址为192.168.1.102

    3. 端口过滤

    tcp.port ==80,  端口为80的

    tcp.srcport == 80,  只显示TCP协议的愿端口为80的。

    4. Http模式过滤

    http.request.method=="GET",   只显示HTTP GET方法的。

    5. 逻辑运算符为 AND/ OR

    常用的过滤表达式

    过滤表达式 用途
    http 只查看HTTP协议的记录
    ip.src ==192.168.1.102 or ip.dst==192.168.1.102  源地址或者目标地址是192.168.1.102
    udp 只查看UDP传输协议

      

    抓包分析UDP协议中的QQ会话

    https://blog.csdn.net/weixin_44448942/article/details/103309355

    https://blog.csdn.net/holandstone/article/details/47026213

    https://blog.csdn.net/qinggebuyao/article/details/7814499

    使用Wireshark抓包分析UDP协议,抓包如下

    • 通过添加udp筛选,抓取了一些包,在列表区可以看到这次抓取过程中每个包的编号、时间、来源和去向IP、协议、长度、信息。
    • 在数据包详细区由上到下分别为:
    1. Frame 211:物理层的数据帧概况
    2. Ethernet II:数据链路层以太网帧头部信息,可以看到路由信息
    3. Internet Protocol Version 4:网络层IP包头部信息,此处是IPv4
    4. User Datagram Protocol:传输层的数据段头部信息,此处是UDP
    5. OICQ:应用层信息,此处是QQ定义的应用层协议
    • 在数据包详细区点击某一个字段可以在数据包字节区查看具体的数据信息

    物理层的数据帧分析

    #211号帧,线路377字节,实际捕获3377字节,接口id
    Frame 211: 377 bytes on wire (3016 bits), 377 bytes captured (3016 bits) on interface DeviceNPF_{4A7CD894-2EED-****-****-ABC****5A3**}, id 0
    #接口id
    Interface id: 0 (DeviceNPF_{4A7CD894-2EED-****-****-ABC****5A3**})
    	#接口名 、接口描述
        Interface name: DeviceNPF_{4A7CD894-2EED-****-****-ABC****5A3**}
        Interface description: 以太网
    #封装类型
    Encapsulation type: Ethernet (1)
    #获取日期和时间
    Arrival Time: Nov  4, 2020 17:23:43.695577000 中国标准时间
    [Time shift for this packet: 0.000000000 seconds]
    #从新纪元时间1970-01-01 00:00:00 UTC算起的时间
    Epoch Time: 1604481823.695577000 seconds
    #此包与前一包和第一包的时间间隔
    [Time delta from previous captured frame: 0.120236000 seconds]
    [Time delta from previous displayed frame: 0.120236000 seconds]
    [Time since reference or first frame: 3.965476000 seconds]
    Frame Number: 211  #帧序号
    Frame Length: 377 bytes (3016 bits)  #帧长度
    Capture Length: 377 bytes (3016 bits) #捕获长度
    [Frame is marked: False]  #此帧是否做了标记:否
    [Frame is ignored: False]  #此帧是否被忽略:否
    [Protocols in frame: eth:ethertype:ip:udp:oicq]  #帧内封装的协议层次结构
    [Coloring Rule Name: UDP] #着色标记的协议名称
    [Coloring Rule String: udp] #着色规则显示的字符串,也就是筛选器

    数据链路层分析

    #路由信息,来源Tp-LinkT (MAC地址d0:76:**:**:**:*1),到达Dell (MAC地址8c:ec:**:**:**:*8)
    Ethernet II, Src: Tp-LinkT_84:**:** (d0:76:**:**:**:*1), Dst: Dell_d0:6f:** (8c:ec:**:**:**:*8)
    Destination: Dell_d0:6f:** (8c:ec:**:**:**:*8)
    Source: Tp-LinkT_84:**:** (d0:76:**:**:**:*1)
    Type: IPv4 (0x0800) #网络层类型为IPv4

    网络层分析

    #IPV4 源地址IP:61.1**.***.**3 目标地址IP:192.168.1.100
    Internet Protocol Version 4, Src: 61.1**.***.**3, Dst: 192.168.1.100
    0100 .... = Version: 4 #IP协议版本
    .... 0101 = Header Length: 20 bytes (5) #IPv4的首部长度 20字节=5*4
    # DS:区分服务 代码点,用来指定特殊的数据包处理方式以获得更好的服务。
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
    Total Length: 363 #指首部和数据的总长度 363
    #IPv4在存储器中维持一个计数器,每产生一个数据包,计数器加一,把值赋给该字段作为标识,共8字节。
    Identification: 0x4584 (17796)
    #目前只有两位有意义。最低位为1表示后面“还有分片”的数据报,为0表示这已经是最后一个数据片;中间一位为1表示“不能分片”,为0才允许分片。
    Flags: 0x4000, Don't fragment
    #片偏移:13位,较长的分组在经过通信链路中因为分组过大进行分片,分片后在原分组中的相对位置。片偏移以8字节为偏移单位
    Fragment offset: 0
    #生存时间:表示数据包在网络中的寿命,缩写TTL,功能是“跳数限制”
    Time to live: 46
    Protocol: UDP (17) #指出此数据包携带数度的协议为UDP
    #首部效验和:数据包每经过一个路由器,路由器都要重新计算一下首部检验和,这里未核实。
    #若首部未发生变化,则此结果必为0,于是就保留这个数据报。这个字段只检验数据报的首部,但不包括数据部分。
    Header checksum: 0x5385 [validation disabled]
    [Header checksum status: Unverified]
    Source: 61.1**.***.**3 #源IP
    Destination: 192.168.1.100 #目标IP

    传输层分析

    #UDP协议,源端口:8000, 目标端口:4020
    User Datagram Protocol, Src Port: 8000, Dst Port: 4020
    Source Port: 8000
    Destination Port: 4020
    Length: 343 #数据报文长度:343字节
    Checksum: 0xe2b0 [unverified] #校验和,未核实
    [Checksum Status: Unverified]
    [Stream index: 0]
    #此包与第一包和前一包的时间戳间隔
    [Timestamps]
        [Time since first frame: 3.965476000 seconds]
        [Time since previous frame: 0.241175000 seconds]

    应用层分析OICQ

    OICQ - IM software, popular in China
    Flag: Oicq packet (0x02) #标识
    Version: 0x3949 #版本号
    Command: Receive message (23) #命令字,这里是接收信息
    Sequence: 7835 #序号
    Data(OICQ Number,if sender is client): 76523**58 #我的qq号
    Data:  #具体数据
        [Expert Info (Warning/Undecoded): Trailing stray characters]
            [Trailing stray characters]
            [Severity level: Warning]
            [Group: Undecoded]

    TCP三次握手

    强烈推荐这个文章TCP 为什么三次握手而不是两次握手(正解版),三次握手是为了让双方的消息序列号同步(即达成互相知道对方知道了自己的序列号,这样自己才能按照自己的序列号可靠地传消息),节省资源只是顺带的结果

     

    最后一次握手在默认不携带数据的情况下, 由于SYN 不是 1 , 是不消耗序列号的。 所以三次握手结束后, 客户端下一个发送的报文中 seq 依旧是 x+1

    TCP数据在IP数据报中的封装

    TCP数据在IP数据报中的封装

     

    TCP包首部


    任意网站三次握手过程和四次挥手过程抓包分析

    使用wireshark抓取网页打开和关闭飞书主页时的TCP报文分析。

    两次抓包时飞书的ip分别为119.167.188.226119.167.188.225

    使用Wireshark抓包分析TCP三次握手,抓包如下

    Alt text

    可以看到192.168.1.100(客户端)通过10625端口发送TCP包到119.167.188.226(服务器端)的443端口(https默认端口),经过TCP三次握手后客户端和服务器互相Say Hello,与HTTPS站点之间使用1.2版本的的TLS协议继续握手,通过证书认证来确认对方的身份,交换密钥。

    首先从抓包列表中可以看到,此次开始信息是符合TCP三次握手的操作的。

    1. 192.168.1.100(客户端)通过10625端口发送TCP包到119.167.188.226(服务器端)的443端口(https默认端口),请求开启连接。
      • 其中包含了SYN标志,表明自己已经进入了SYN-SENT状态。
      • 此次消息在客户端的序列Seq=0,由于之前从未连接过,所以并未携带确认序号ACK。
    2. 服务器端给客户端回复TCP包,表明确认收到了客户端想要开启连接的意图。
      • 其中包含了SYN标志,表明自己已经进入了SYN-RCVD状态。
      • 消息序号Seq=0,期望收到客户端的消息序号ACK为1,即上一个包中客户端的Seq(0)+1,这就是TCP确保消息序列的顺序可靠性的实现。
    3. 客户端给服务器端回复TCP包,表明确认收到了服务器端刚刚发来的确认信息。
      • 此时客户端已经认为与服务器端建立了连接,后续可以进行数据传输。
      • 消息序号Seq=1为上一次服务器端发来的包中的ACK;期望收到对方的消息序号ACK=1为上一次服务器端发来的包中的Seq+1。
      • 经过网路传输后,服务器端收到此包后建立连接。

    三次握手的包内传输层分别如下图

    TCP和UDP不同的在于传输层部分,由于第一个实验已经分析过其他部分,此处只分析传输层部分。

    Alt text

    第一个包的传输层头部分析:

    #TCP协议,源端口:10625, 目标端口:443, 源序号Seq=0,报文无内容只有头部,所以长度为0
    Transmission Control Protocol, Src Port: 10625, Dst Port: 443, Seq: 0, Len: 0
    Source Port: 10625
    Destination Port: 443
    [Stream index: 14]
    [TCP Segment Len: 0]
    Sequence number: 0    (relative sequence number)
    Sequence number (raw): 661788229 #32位序号
    [Next sequence number: 1    (relative sequence number)]
    Acknowledgment number: 0
    Acknowledgment number (raw): 0
    #4位首部长度,长度为32字节
    1000 .... = Header Length: 32 bytes (8)
    #标志位,其中前3位为预留字段(Reserved field),值全为零。预留给以后使用。
    Flags: 0x002 (SYN)
        000. .... .... = Reserved: Not set #保留字段,预留给以后使用。
    	#当前TCP首部中有9个标志比特。它们中的多个可同时被设置为1。
        ...0 .... .... = Nonce: Not set #该标签用来保护不受发送者发送的突发的恶意隐藏报文的侵害。
        .... 0... .... = Congestion Window Reduced (CWR): Not set #发送者在接收到一个带有ECE flag包时,将会使用CWR flag。
        .... .0.. .... = ECN-Echo: Not set #ECN表示Explicit Congestion Notification。表示TCP peer有ECN能力。
        .... ..0. .... = Urgent: Not set #是否使用紧急指针
        .... ...0 .... = Acknowledgment: Not set #确认序号
        .... .... 0... = Push: Not set #催促接收方应该尽快将这个报文段交给应用层
        .... .... .0.. = Reset: Not set #重建连接
        .... .... ..1. = Syn: Set #同步序号,用来发起一个连接
            [Expert Info (Chat/Sequence): Connection establish request (SYN): server port 443]
        .... .... ...0 = Fin: Not set #结束信号,发端完成发送任务
        [TCP Flags: ··········S·]
    #窗口(Window):长度2个字节。表示滑动窗口的大小,用来告诉发送端接收端的buffer space的大小。接收端buffer大小用来控制发送端的发送数据数率,从而达到流量控制。最大值为65535.
    Window size value: 64240
    [Calculated window size: 64240]
    #校验和(Checksum):长度2个字节。用来检查TCP头在传输中是否被修改。
    Checksum: 0x1496 [unverified]
    [Checksum Status: Unverified]
    #紧急指针(Urgent pointer):长度为2个字节。表示TCP片中第一个紧急数据字节的指针。只有当前面的标志位中的URG标志置1时紧急指针才有效。
    Urgent pointer: 0
    #TCP选项,长度不定,但必须是4字节的整数倍,此处为12字节长度。
    Options: (12 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), SACK permitted
    	#最大片段长度,指明本端可以接受的最大长度的TCP Segment(Payload,不含TCP Header),也就是说,对端发送数据的长度不应该大于MSS(单位Byte)。
        TCP Option - Maximum segment size: 1460 bytes #最大可接受片段长度1460字节,此选项占据了4个字节
        TCP Option - No-Operation (NOP) #无意义,主要是填充整体长度至4字节的整数倍,占据1个字节
    	#将TCP Header的Window Size字段从16bit扩展至最多30bit。
        TCP Option - Window scale: 8 (multiply by 256) #此处为扩展了8bit,数据容量乘以256,此选项占据3字节
        TCP Option - No-Operation (NOP) #无意义,主要是填充整体长度至4字节的整数倍,占据1个字节
        TCP Option - No-Operation (NOP) #无意义,主要是填充整体长度至4字节的整数倍,占据1个字节
    	#TCP收到乱序数据后,会将其放入乱序队列中,然后发送重复ACK给对端。对端收到多个重复的ACK后,就会推测到可能发生了数据丢失,再重传数据。如果乱序的数据比较零散,则这种机制的效率会很低。使用SACK选项可以告知发包方收到了哪些数据,发包方收到这些信息后就会知道哪些数据丢失,然后立即重传缺失部分即可。这就大大提高了数据重传的速度。
        TCP Option - SACK permitted #若要使用SACK特性,必须在建立连接时,在SYN Segment中附加上SACK-Permitted Option,以此告知对方自己支持SACK,此选项占据2字节。
    #此包与第一包和前一包的时间戳间隔
    [Timestamps]
        [Time since first frame in this TCP stream: 0.000000000 seconds]
        [Time since previous frame in this TCP stream: 0.000000000 seconds]
    

      

    Alt text

    第二个包的传输层头部分析,仅分析不同之处:

    #TCP协议,源端口:443, 目标端口:10625, 源序号Seq=0,确认序号ACK=1,长度为0
    Transmission Control Protocol, Src Port: 443, Dst Port: 10625, Seq: 0, Ack: 1, Len: 0
    Source Port: 443
    Destination Port: 10625
    [Stream index: 14]
    [TCP Segment Len: 0]
    Sequence number: 0    (relative sequence number)
    Sequence number (raw): 935016043
    [Next sequence number: 1    (relative sequence number)]
    Acknowledgment number: 1    (relative ack number)
    Acknowledgment number (raw): 661788230 #32位确认序号
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x012 (SYN, ACK)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...1 .... = Acknowledgment: Set #此处表明有ACK标志
        .... .... 0... = Push: Not set
        .... .... .0.. = Reset: Not set
        .... .... ..1. = Syn: Set #同步序号,用来发起连接
            [Expert Info (Chat/Sequence): Connection establish acknowledge (SYN+ACK): server port 443]
        .... .... ...0 = Fin: Not set
        [TCP Flags: ·······A··S·]
    Window size value: 29200
    [Calculated window size: 29200]
    Checksum: 0x2f4a [unverified]
    [Checksum Status: Unverified]
    Urgent pointer: 0
    Options: (12 bytes), Maximum segment size, No-Operation (NOP), No-Operation (NOP), SACK permitted, No-Operation (NOP), Window scale
        TCP Option - Maximum segment size: 1448 bytes #最大可接受片段长度1448字节,此选项占据了4个字节
        TCP Option - No-Operation (NOP)
        TCP Option - No-Operation (NOP)
        TCP Option - SACK permitted #以此告知对方自己支持SACK,此选项占据2字节。
        TCP Option - No-Operation (NOP)
        TCP Option - Window scale: 9 (multiply by 512) #此处为扩展了9bit,数据容量乘以512,此选项占据3字节
    [SEQ/ACK analysis]
    [Timestamps]
        [Time since first frame in this TCP stream: 0.015611000 seconds]
        [Time since previous frame in this TCP stream: 0.015611000 seconds]
    

      

    Alt text

    第三个包的传输层头部分析,仅分析不同之处:

    #TCP协议,源端口:10625, 目标端口:443, 源序号Seq=1,确认序号ACK=1,长度为0
    Transmission Control Protocol, Src Port: 10625, Dst Port: 443, Seq: 1, Ack: 1, Len: 0
    Source Port: 10625
    Destination Port: 443
    [Stream index: 14]
    [TCP Segment Len: 0]
    Sequence number: 1    (relative sequence number)
    Sequence number (raw): 661788230
    [Next sequence number: 1    (relative sequence number)]
    Acknowledgment number: 1    (relative ack number)
    Acknowledgment number (raw): 935016044
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x010 (ACK)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...1 .... = Acknowledgment: Set
        .... .... 0... = Push: Not set
        .... .... .0.. = Reset: Not set
        .... .... ..0. = Syn: Not set #没有了同步序号SYN
        .... .... ...0 = Fin: Not set
        [TCP Flags: ·······A····]
    Window size value: 514
    [Calculated window size: 131584]
    [Window size scaling factor: 256]
    Checksum: 0xe020 [unverified]
    [Checksum Status: Unverified]
    Urgent pointer: 0
    #没有了选项
    [SEQ/ACK analysis]
    [Timestamps]
        [Time since first frame in this TCP stream: 0.015702000 seconds]
        [Time since previous frame in this TCP stream: 0.000091000 seconds]

    使用Wireshark抓包分析TCP四次挥手,抓包如下

    Alt text

    和实验一共同的部分就不再赘述了 首先从抓包列表中可以看到,此次结束信息是符合四次握手的操作的,和一般不同的是这次挥手是由于连接超时,服务器先发起的挥手。

    1. 119.167.188.225(服务器端)通过443端口(https默认端口)发送TCP包到192.168.1.100(客户端)的10354端口,用来关闭服务器到客户端的数据传送。
      • 其中包含了FIN标志,表明自己已经进入了FIN-WAIT状态。
      • 此次消息在服务器端的序列Seq=70058,期望收到客户端的消息序号ACK为114。
    2. 客户端给服务器端回复TCP包,表明确认收到了服务器想要关闭连接的意图。
      • 消息序号Seq=114,期望收到服务器端的消息序号ACK为70059,即上一个包中服务器端的Seq(70058)+1,这就是TCP确保消息序列的顺序可靠性的实现。
    3. 客户端给服务器端发送TCP包,表明自己已经准备好了关闭连接。
      • 其中包含了FIN标志,表明自己已经进入了准备接收对方最后一个消息的LAST-ACK状态。
      • 消息序号Seq=114,期望收到服务器端的最后消息序号ACK为70059,由于上一次没有要传输的数据,复用上次的序号。
    4. 服务器端给客户端回复TCP包,表明确认收到了客户端已经准备好关闭连接的信号。
      • 此时服务器已经进入了TIME_WAIT的状态,将在等待2个最大报文段最大生存时间MSL(Maximum Segment Lifetime)后关闭连接。
      • 消息序号Seq=70055为上一次客户端发来的包中的ACK;期望收到对方的消息序号ACK=115为上一次客户端发来的包中的Seq+1,尽管对方不会再发消息了。
      • 经过网路传输后,客户端收到此包后关闭连接。

    注意到服务器端发给客户端的包为60字节,而客户端发给服务器的包为54字节,应该是上下行的网卡加的,所以抓包时从本机发出的包是还没有加填充的。

    四次挥手的包内传输层分别如下图

    Alt textAlt textAlt textAlt text

    TCP和UDP不同的在于传输层部分,以第一个包的传输层头部为例进行分析

    #TCP协议,源端口:443, 目标端口:10354, 源序号Seq=70058,期待目标确认序号ACK=114,报文无内容只有头部,所以长度为0
    Transmission Control Protocol, Src Port: 443, Dst Port: 10354, Seq: 70058, Ack: 114, Len: 0
    Source Port: 443
    Destination Port: 10354
    [Stream index: 56]
    [TCP Segment Len: 0]
    Sequence number: 70058    (relative sequence number)
    Sequence number (raw): 4009911588 #32位序号
    [Next sequence number: 70059    (relative sequence number)]
    Acknowledgment number: 114    (relative ack number)
    Acknowledgment number (raw): 1563211395 #32位确认序号
    #4位首部长度,长度为20字节
    0101 .... = Header Length: 20 bytes (5)
    #标志位,其中前3位为预留字段(Reserved field),值全为零。预留给以后使用。
    Flags: 0x011 (FIN, ACK)
        000. .... .... = Reserved: Not set #保留字段,预留给以后使用。
    	#当前TCP首部中有9个标志比特。它们中的多个可同时被设置为1。
        ...0 .... .... = Nonce: Not set #该标签用来保护不受发送者发送的突发的恶意隐藏报文的侵害。
        .... 0... .... = Congestion Window Reduced (CWR): Not set #发送者在接收到一个带有ECE flag包时,将会使用CWR flag。
        .... .0.. .... = ECN-Echo: Not set #ECN表示Explicit Congestion Notification。表示TCP peer有ECN能力。
        .... ..0. .... = Urgent: Not set #是否使用紧急指针
        .... ...1 .... = Acknowledgment: Set #确认序号
        .... .... 0... = Push: Not set #催促接收方应该尽快将这个报文段交给应用层
        .... .... .0.. = Reset: Not set #重建连接
        .... .... ..0. = Syn: Not set #同步序号,用来发起一个连接
        .... .... ...1 = Fin: Set #结束信号,发端完成发送任务
            [Expert Info (Chat/Sequence): Connection finish (FIN)]
                [Connection finish (FIN)]
                [Severity level: Chat]
                [Group: Sequence]
        [TCP Flags: ·······A···F]
    #窗口(Window):长度2个字节。表示滑动窗口的大小,用来告诉发送端接收端的buffer space的大小。接收端buffer大小用来控制发送端的发送数据数率,从而达到流量控制。最大值为65535.
    Window size value: 66
    [Calculated window size: 66]
    [Window size scaling factor: -1 (unknown)]
    #校验和(Checksum):长度2个字节。用来检查TCP头在传输中是否被修改。
    Checksum: 0x26f8 [unverified]
    [Checksum Status: Unverified]
    #紧急指针(Urgent pointer):长度为2个字节。表示TCP片中第一个紧急数据字节的指针。只有当前面的标志位中的URG标志置1时紧急指针才有效。
    Urgent pointer: 0
    #此包与第一包和前一包的时间戳间隔
    [Timestamps]
        [Time since first frame in this TCP stream: 120.058793000 seconds]
        [Time since previous frame in this TCP stream: 0.000000000 seconds]
    

      


    问题:为什么TCP关闭连接是四次挥手呢?

    https://www.cnblogs.com/GuoXinxin/p/11657933.html

     

     由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。

    1. 第一次挥手:A->B,A向B发出释放连接请求的报文,其中FIN(终止位) = 1,seq(序列号)=u;在A发送完之后,A的TCP客户端进入FIN-WAIT-1(终止等待1)状态。此时A还是可以进行收数据的
    2. 第二次挥手:B->A:B在收到A的连接释放请求后,随即向A发送确认报文。其中ACK=1,seq=v,ack(确认号) = u +1;在B发送完毕后,B的服务器端进入CLOSE_WAIT(关闭等待)状态。此时A收到这个确认后就进入FIN-WAIT-2(终止等待2)状态,等待B发出连接释放的请求。此时B还是可以发数据的。(如果 B 直接跑路,则 A 永远处与这个状态。TCP 协议里面并没有对这个状态的处理,但 Linux 有,可以调整 tcp_fin_timeout 这个参数,设置一个超时时间。)
    3. 第三次挥手:B->A:当B已经没有要发送的数据时,B就会给A发送一个释放连接报文,其中FIN=1,ACK=1,seq=w,ack=u+1,在B发送完之后,B进入LAST-ACK(最后确认)状态。
    4. 第四次挥手:A->B;当A收到B的释放连接请求时,必须对此发出确认,其中ACK=1,seq=u+1,ack=w+1;A在发送完毕后,进入到TIME-WAIT (时间等待)状态。B在收到A的确认之后,进入到CLOSED(关闭)状态。在经过时间等待计时器设置的时间之后,A才会进入CLOSED状态。

     为什么需要TIME_WAIT?

    TIMEWAIT状态也称为2MSL等待状态

     1)为实现TCP这种全双工(full-duplex)连接的可靠释放

    这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。

    2)为使旧的数据包在网络因过期而消失

    每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime)。它是任何报文段被丢弃前在网络内的最长时间(一个来回,所以乘以2)。

    为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

     这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,我们也未必全部数据都发送给对方了,所以我们不可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,我们的ACK和FIN一般都会分开发送。

    有三次挥手的情况么?该情况是在协议中实现的么?

    如果是三次挥手,会怎么样?三次的话,被动关闭端在收到FIN消息之后,需要同时回复ACK和Server端的FIN消息。如果Server端在该连接上面并没有Pending的消息要处理,那么是可以的,如果Server端还需要等待一段时间才可以关闭另外一个方向的连接,那么这样的三次挥手就不能满足条件。


    分析ping下的ICMP报文格式

    使用wireshark抓取ping飞书主页时的ICMP报文,并分析包中的结构和数据。

    指令: ping feishu.cn 

    抓包时飞书的ip为122.14.230.135,结果如图,有来有回总共8个包,分为4组请求和回复,均为ICMP查询报文。

    Alt text

    ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议簇的一个子协议,用于在IP主机、路由版器之间传递权控制消息.

    ICMP报文的种类有两种,即ICMP差错报告报文和ICMP询问报文。

    ICMP 协议介于传输层和网络层之间。不能说它是网络层协议,是因为它依赖于所有的 IP 协议实现,ICMP 报文在传输过程中,又很可能被传输层解析处理。尽管如此,我们通常仍然认为 ICMP 协议是网络层协议。维基百科对此有如下解释:

    ICMP 协议使用了 IP 协议的基本支持,以至于它好像是更高层的协议。然而, ICMP 协议实际上是 IP 协议的一个组成部分。尽管 ICMP 报文被封装在标准 IP 协议包中,但与一般的 IP 包处理不同,ICMP 报文通常作为特殊情况处理。

    (ICMP uses the basic support of IP as if it were a higher level protocol, however, ICMP is actually an integral part of IP. Although ICMP messages are contained within standard IP packets, ICMP messages are usually processed as a special case, distinguished from normal IP processing. )

    关于ICMP报文的背景知识参考ICMP报文

    Alt text

    ICMP报文的具体格式

    请求包分析

    Alt text

    仅分析ICMP报文部分

    #ICMP协议
    Internet Control Message Protocol
    #8位类型,Type为8是请求回复报文(Echo)
    Type: 8 (Echo (ping) request)
    #占8位,Type和Code一起决定了ICMP报文的类型。
    Code: 0 
    #16位的检验和字段,包含数据在内的整个ICMP数据包的检验和,其计算方法和IP头部检验和的计算方法一样的。
    Checksum: 0x4a0f [correct] #检验和正确
    [Checksum Status: Good]
    #ICMP报文中的标识符和序列号字段由发送端任意选择设定,这些值在应答中将被返回,这样,发送端就可以把应答与请求进行匹配。
    #标识符
    Identifier (BE): 1 (0x0001)
    Identifier (LE): 256 (0x0100)
    #序列编号
    Sequence number (BE): 844 (0x034c)
    Sequence number (LE): 19459 (0x4c03)
    [Response frame: 6]
    #请求回复的数据
    Data (32 bytes)
    

      

    回复包分析

    Alt text

    #ICMP协议
    Internet Control Message Protocol
    #8位类型,Type为0是回复报文(Echo reply)
    Type: 0 (Echo (ping) reply)
    #占8位,Type和Code一起决定了ICMP报文的类型。
    Code: 0
    #16位的检验和字段,包含数据在内的整个ICMP数据包的检验和,其计算方法和IP头部检验和的计算方法一样的。
    Checksum: 0x520f [correct] #检验和正确
    [Checksum Status: Good]
    #ICMP报文中的标识符和序列号字段由发送端任意选择设定,这些值在应答中将被返回,这样,发送端就可以把应答与请求进行匹配。
    #标识符
    Identifier (BE): 1 (0x0001)
    Identifier (LE): 256 (0x0100)
    #序列编号
    Sequence number (BE): 844 (0x034c)
    Sequence number (LE): 19459 (0x4c03)
    [Request frame: 5]
    #通过在ICMP报文中存放发送请求的时间值来计算往返时间。当应答返回时,用当前时间减去存放在ICMP报文中的时间值,即是往返时间。
    [Response time: 29.905 ms] #回复用时29.905 ms
    #回复的数据
    Data (32 bytes)
    

      

  • 相关阅读:
    【js】数据表格开启同比化显示,增加对比性
    Kotlin 使用协程编写高效的并发程序
    Kotlin泛型的高级特性
    kotlin基础
    Java接口和抽象类区别
    Java内存泄漏
    jmeter,注意:您可以通过定义属性resultcollector.action_if_file_exists来避免这个弹出框
    性能测试术语
    jenkins正常显示jmeter的html报告设置
    jmeter: beanshell后置处理程序,清空文件和保存json提取器提取的数据到文件中
  • 原文地址:https://www.cnblogs.com/smileglaze/p/13926489.html
Copyright © 2011-2022 走看看