lwip学习——TCP协议

TCP 是一个面向连接的协议,无论哪一方向另一方发送数据之前,都必须先在双方之 间建立一条连接,俗称“握手”。

使用TCP协议进行通信的双方主机在进行数据传输之前,必须使用“三次报文握手”来建立TCP连接。

TCP连接建立成功后才能进行数据传输,数据传输完成后必须使用“四次报文挥手”来释放TCP连接

而TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。

TCP报文段简介

TCP报文段也分为首部和数据两部分,首部默认情况下一般是20字节长度,但在一些需求情况下,会使用“可选字段”,这时,首部长度会有所增加,但最长不超过60字节。

TCP 首部包含以下内容,请留意其中的控制位,在三次握手和四次挥手过程中会频繁出现:

  • 端口号 (Source Port and Destination Port):每个 TCP 报文段都包含源端和目的端的端口号,用于寻找发送端和接收端应用进程。这两个值加上 IP 首部中的源端 IP 地址和目的端 IP 地址就可以确定一个唯一的 TCP 连接。
  • 序号 (Sequence Number):这个字段的主要作用是用于将失序的数据重新排列。TCP 会隐式地对字节流中的每个字节进行编号,而 TCP 报文段的序号被设置为其数据部分的第一个字节的编号。序号是 32 bit 的无符号数,取值范围是0到 232 - 1。
  • 确认序号 (Acknowledgment Number):接收方在接受到数据后,会回复确认报文,其中包含确认序号,作用就是告诉发送方自己接收到了哪些数据,下一次数据从哪里开始发,因此,确认序号应当是上次已成功收到数据字节序号加 1。只有 ACK 标志为 1 时确认序号字段才有效。
  • 首部长度 (Header Length):首部中的选项部分的长度是可变的,因此首部的长度也是可变的,所以需要这个字段来明确表示首部的长度,这个字段占 4 bit,4 位的二进制数最大可以表示 15,而首部长度是以 4 个字节为一个单位的,因此首部最大长度是 15 * 4 = 60 字节。
  • 保留字段 (Reserved):占 6 位,未来可能有具体用途,目前默认值为0.
  • 控制位 (Control Bits):在三次握手和四次挥手中会经常看到 SYN、ACK 和 FIN 的身影,一共有 6 个标志位,它们表示的意义如下:
    • URG (Urgent Bit):值为 1 时,紧急指针生效
    • ACK (Acknowledgment Bit):值为 1 时,确认序号生效
    • PSH (Push Bit):接收方应尽快将这个报文段交给应用层
    • RST (Reset Bit):发送端遇到问题,想要重建连接
    • SYN (Synchronize Bit):同步序号,用于发起一个连接
    • FIN (Finish Bit):发送端要求关闭连接
  • 窗口大小 (Window):TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个 16 bit 字段,单位是字节, 因而窗口大小最大为 65535 字节。
  • 检验和 (Checksum):功能类似于数字签名,用于验证数据完整性,也就是确保数据未被修改。检验和覆盖了整个 TCP 报文段,包括 TCP 首部和 TCP 数据,发送端根据特定算法对整个报文段计算出一个检验和,接收端会进行计算并验证。
  • 紧急指针 (Urgent Pointer):当 URG 控制位值为 1 时,此字段生效,紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。
  • 选项 (Options):这一部分是可选字段,也就是非必须字段,最常见的可选字段是“最长报文大小 (MSS,Maximum Segment Size)”。
  • 有效数据部分 (Data):这部分也不是必须的,比如在建立和关闭 TCP 连接的阶段,双方交换的报文段就只包含 TCP 首部。

 关于 TCP

  • TCP 提供一种面向连接的、可靠的字节流服务
  • 在一个 TCP 连接中,仅有两方进行彼此通信。广播和多播不能用于 TCP
  • TCP使用校验和,确认和重传机制来保证可靠传输
  • TCP给数据分节进行排序,并使用累积确认保证数据的顺序不变和非重复
  • TCP 使用滑动窗口机制来实现流量控制,通过动态改变窗口的大小进行拥塞控制
  • TCP并不能保证数据一定会被对方接收到,因为这是不可能的。它不是100%可靠的协议,它所能提供的是数据的可靠传递或故障的可靠通知。

初识“三次握手”

三次握手是TCP协议用于建立可靠连接的过程,其步骤如下:

  • 第一次握手(SYN):客户端向服务器发送SYN包,请求建立连接。该包中包含一个随机生成的初始序列号ISN(Initial Sequence Number)。
  • 第二次握手(SYN+ACK):服务器收到SYN包后,向客户端发送SYN+ACK包,表示同意建立连接。该包中也包含一个随机生成的序列号ISN,同时将确认序列号ACK设置为客户端的ISN+1。
  • 第三次握手(ACK):客户端收到服务器的SYN+ACK包后,向服务器发送ACK包,表示客户端也同意建立连接。该包的序列号设置为服务器的ISN+1,确认序列号设置为服务器的ISN+1。
    在三次握手完成后,TCP连接建立成功,双方可以开始进行数据传输。这个过程可以确保连接的可靠性和完整性,防止数据包的丢失或重复传输。

三次握手的作用

三次握手的作用如下:

  • 建立可靠连接:三次握手可以确保客户端和服务器之间建立起可靠的连接,防止数据包的丢失或重复传输。
  • 防止旧连接的混淆:由于网络延迟等原因,可能会出现旧连接的数据包在新连接中被误认为是有效数据包的情况。而三次握手过程中随机生成的ISN可以防止这种情况的发生。
  • 防止恶意连接:三次握手可以防止未经授权的恶意连接,例如SYN洪泛攻击等。如果服务器收到的SYN包并没有相应的ACK包,那么服务器就不会认为这是一条有效的连接请求,从而防止恶意连接。

总之,三次握手是TCP协议用于建立可靠连接的基本过程,其作用在于确保连接的可靠性、完整性和安全性

LwIP 中定义的 TCP 状态 

TCP 状态转移图

虚线:表示服务器的状态转移。

实线:表示客户端的状态转移。

图中所有“关闭”、“打开”都是应用程序主动处理。

图中所有的“超时”都是内核超时处理。

三次握手过程

(7):服务器的应用程序主动使服务器进入监听状态,等待客户端的连接请求

(1):首先客户端的应用程序会主动发起连接,发送 SNY 报文段给服务器, 在发送之后就进入 SYN_SENT 状态等待服务器的 SNY ACK 报文段进行确认,如果在指定 超时时间内服务器不进行应答确认,那么客户端将关闭连接。

(8):处于监听状态的服务器收到客户端的连接请求(SNY 报文段),那么服 务器就返回一个 SNY ACK 报文段应答客户端的响应,并且服务器进入 SYN_RCVD 状态。

(2):如果客户端收到了服务器的 SNY ACK 报文段,那么就进入 ESTABLISHED 稳定连接状态,并向服务器发送一个 ACK 报文段。

(9):同时,服务器收到来自客户端的 ACK 报文段,表示连接成功,进入 ESTABLISHED 稳定连接状态,这正是我们建立连接的三次握手过程。

四次挥手过程

(3):一般来说,都是客户端主动发送一个 FIN 报文段来终止连接,此时客户 端从 ESTABLISHED 稳定连接状态转移为 FIN_WAIT_1 状态,并且等待来自服务器的应答 确认。

(10):服务器收到 FIN 报文段,知道客户端请求终止连接,那么将返回一个 ACK 报文段到客户端确认终止连接,并且服务器状态由稳定状态转移为 CLOSE_WAIT 等 待终止连接状态。

(4):客户端收到确认报文段后,进入 FIN_WAIT_2 状态,等待来自服务器的 主动请求终止连接,此时{客户端->服务器}方向上的连接已经断开。

(11):一般来说,当客户端终止了连接之后,服务器也会终止{服务器->客户 端}方向上的连接,因此服务器的原因程序会主动关闭该方向上的连接,发送一个 FIN 报文 段给客户端。

(5):处于 FIN_WAIT_2 的客户端收到 FIN 报文段后,发送一个 ACK 报文段 给服务器。

(12):服务器收到 ACK 报文段,就直接关闭,此时{服务器->客户端}方向上 的连接已经终止,进入 CLOSED 状态。

(6):客户端还会等待 2MSL,以防 ACK 报文段没被服务器收到,这就是四次 挥手的全部过程。

参考 野火 LwIP 应用开发实战指南

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值