网络协议(十)-传输层(连接管理)

时间:2021-7-5 作者:qvyue

以下内容来自于小码哥”网络协议从入门到底层原理”

网络协议(十)-传输层(连接管理)
image.png
网络协议(十)-传输层(连接管理)
image.png
分析一下自己抓包的结果
网络协议(十)-传输层(连接管理)
image.png

上图是一个典型的三次握手
我们来分析一下第一次握手

  • 第一次握手

    网络协议(十)-传输层(连接管理)
    image.png

第一次握手的数据部分的长度是0个字节, TCP首部占44个字节, 其中固定部分长度是20个字节, 选项部分长度是24个字节

TCP首部存储的是Sequenceraw值,而不是相对值 见下图

网络协议(十)-传输层(连接管理)
image.png

我们把这个值称为s1, 这个s1记录的是客户端->服务器发送的每一个segment的第一个字节的编号

  • 我们来分析一下第二次握手

    网络协议(十)-传输层(连接管理)
    image.png
  • 我们来分析一下第三次握手

    网络协议(十)-传输层(连接管理)
    image.png

三次握手后, TCP连接就成功建立
建立了发数据的通道, 这是一个全双工的通道, 即客户端也可以发给服务器, 服务器也可以发给客户端

  • 然后客户端发给服务器HTTP请求

    网络协议(十)-传输层(连接管理)
    image.png
  • 服务端收到客户端发过来的HTTP请求之后, 就会发给客户端一个收到的ACK响应

    网络协议(十)-传输层(连接管理)
    image.png
  • 然后服务端就开始发数据给客户端了

    网络协议(十)-传输层(连接管理)
    image.png

看上图可以知道: 上图的ACK全部是719, 这是为什么呢? 719ACK的相对值, 即718 + 1 = 719, 718是客户端发给服务器的HTTP请求的长度, 即TCP的数据部分, 所以ACKraw值应该是期望客户端发给服务器的下一个包的第一个字节的值, 即s1 + b1 + 1, 因为在这个过程中, 并没有收到客户端发给服务器的任何数据包, 那么这个值就始终是s1 + b1 + 1, 相对值就始终是719.

但是会变化的是序号seq值, seq值是上一个包的seq值, 加上长度Len生成的, 比如上图中最后一个包的seq4771, 而4771 = 4755 + 16, 4755就是上一个服务器发给客户端包的seq值. 如果把上图这7个包的长度分别记为k1, k2, k3, k4, k5, k6, k7的话, 那么最后一个包的seq相对值就是1 + k1 + k2 + k3 + k4 + k5 + k6, raw值就是s2 + 1 + k1 + k2 + k3 + k4 + k5 + k6,

让我们看看是不是这样, 我们点开最后一个包:

网络协议(十)-传输层(连接管理)
image.png
网络协议(十)-传输层(连接管理)
image.png

s2的值果然就是这样

  • 接下来就是客户端对服务端的ACK回应, 告诉客户端, 我收到包了:
网络协议(十)-传输层(连接管理)
image.png

注意看最后一个包的ACK6223, 这就是服务器发给客户端的最后一个包的seq + Len:

网络协议(十)-传输层(连接管理)
image.png
  • 就这样反反复复, 直到服务端这边已经发完了全部数据, 那么就会给客户端返回一个200:
    网络协议(十)-传输层(连接管理)
    image.png

从上面的图可以看到, 客户端这边发的好多包的seq都为719, 这是因为客户端发的包都只是一个ACK回应, 表示: 哦, 我收到了, 这样的包的长度Len都为0, 所以seq都为s1 + b1 + 1, 就是相对值为719(718 + 1), raw值为2751725119(718 + 1 + s1(2751724400))

到此, 传输层的三次握手就分析完了.

TCP-建立连接-状态解读
  • CLOSED: client处于关闭状态
  • LISTEN: server处于监听状态, 等待client连接
  • SYN-RCVD: 表示server接受到了SYN报文, 当收到clientACK报文后, 它会进入到ESTABLISHED状态
  • SYN-SENT:表示client已发送SYN报文, 等待server的第2次握手

    网络协议(十)-传输层(连接管理)
    image.png
TCP-建立连接-前2次握手的特点
  • SYN都设置为1

  • 数据部分的长度都为0

  • TCP头部的长度一般是32字节
    — 固定头部: 20字节
    — 选项部分: 12字节

  • 双方会交换确认一些信息
    — 比如MSS, 是否支持SACK, Window scale(窗口缩放系数)等

TCP-建立连接-疑问
  • 为什么建立连接的时候, 要进行3次握手, 2次不行吗?
    — 主要目的: 防止server端一直等待, 浪费资源

  • 如果建立连接只需要2次握手, 可能会出现的情况
    — 假设client发出的第一个连接请求报文段, 因为网络延迟, 在连接释放以后的某个时间才到达server
    — 本来这是一个早已失效的请求, 但server收到此失效的请求后, 误认为是client再次发出的一个新的连接请求
    — 于是server就向client发出确认报文段, 同意建立连接
    — 如果不采用”3次握手”, 那么只要server发出确认, 新的连接就建立了
    — 由于现在client并没有真正想连接服务器的意愿, 因此不会理睬server的确认, 也不会向server发送数据
    — 但在server却以为新的连接已经建立, 并一直等待client发来数据, 这样, server的很多资源就白白浪费了

  • 采用”三次握手”的办法可以防止上述现象发生
    — 例如上述情况, client没有向server的确认发出确认, server由于收不到确认, 就知道client并没有要求建立连接

  • 3次握手失败了, 会怎么处理?
    — 此时server的状态为SYN-RCVD, 若等不到clientACK, server会重新发送SYN+ACK
    — 如果server多次重发SYN+ACK都等不到clientACK, 就会发送RST包, 强制关闭连接

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。