LWIP_TCP 协议

目录

1 TCP 协议简介

1.1 TCP 协议简介

1.2 TCP 的建立连接

1.3 TCP 终止连接

1.4 TCP 报文结构

 1.5 lwIP 的 TCP 报文首部数据结构

1.6 lwIP 的 TCP 连接状态图

 


1 TCP 协议简介

1.1 TCP 协议简介

        TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

        TCP 为了保证数据包传输的可靠行,会给每个包一个序号,同时此序号也保证了发送到接收端主机能够按序接收。然后接收端主机对成功接收到的数据包发回一个相应的确认字符( ACK, Acknowledgement),如果发送端主机在合理的往返时延( RTT) 内未收到确认字符ACK,那么对应的数据包就被认为丢失并将被重传。 TCP 协议,它是基于连接的一种传输层协议,在发送数据之前要求系统需要在不可靠的信道上建立可靠连接,我们称之为“三次握手”。 建立连接完成之后客户端与服务器才能互发数据, 不需要发送数据时,可以断开连接,这里我们称之为“四次挥手”。

1.2 TCP 的建立连接

        握手之前主动打开连接的客户端结束 CLOSED 阶段,被动打开的服务器端也结束CLOSED 阶段,并进入 LISTEN 阶段。随后开始“三次握手”:

① TCP 服务器进程先创建传输控制块 TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了 LISTEN(监听)状态。

② TCP 客户进程也是先创建传输控制块 TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位 SYN=1,同时选择一个初始序列号 seq=x ,此时, TCP 客户端进程进入了SYN-SENT(同步已发送状态)状态。 TCP 规定, SYN 报文段(SYN=1 的报文段)不能携带数据,但需要消耗掉一个序号。

③ TCP 服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该ACK=1, SYN=1,确认号是 ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时, TCP服务器进程进入了 SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。

④ TCP 客户进程收到确认后,还要向服务器给出确认。确认报文的 ACK=1, ack=y+1,自己的序列号 seq=x+1,此时, TCP 连接建立,客户端进入 ESTABLISHED(已建立连接)状态。 TCP 规定, ACK 报文段可以携带数据,但是如果不携带数据则不消耗序号。

当服务器收到客户端的确认后也进入 ESTABLISHED 状态,此后双方就可以开始通信了。这就是“三次握手”的过程,如下图所示。

1.3 TCP 终止连接

        建立一个连接需要三次握手而终止一个连接需要四次挥手,终止连接有以下过程。

(1) 第一次挥手:客户端发送释放报文,并停止发送数据。释放数据报文首部, FIN=1,其序列号为 seq=u,此时,客户端进入 FIN-WAIT1(等待服务器应答 FIN 报文)。

(2) 第二次挥手:服务器收到客户端的 FIN 报文后,发出确认报文 ACK=1、 ack=u+1,并携带自己的序列号 seq=v。此时,服务器进入 CLOSE-WAIT(关闭等待) 状态。客户端收到服务端确认请求,此时,客户端进入 FIN-WAIT2(终止等待 2)状态,等待服务器发送连接释放报文。

(3) 第三次挥手:服务器向客户端发送连接释放报文 FIN=1、 ack=u+1,此时,服务器进入了 LAST-ACK(最后确认)等待客户端的确认。客户端接收到服务器的连接释放报文后,必须发送确认 ack=1、 ack=w+1,客户端的序列号为 seq=u+1,此时,客户端进入 TIME-WAIT(时间等待)。

(4) 第四次挥手:服务器接收到客户端的确认报文,立刻进入 CLOSED 状态。

这四次挥手就是终止 TCP 协议连接,如下图所示:

1.4 TCP 报文结构

        在传输层中, TCP 的数据包称为数据段, TCP 报文段与 UDP 报文段一样都是封装在 IP 数据报中发送。 TCP 首部包含建立与断开、数据确认、窗口大小通告、数据发送相关的所有标志和控制信息, TCP 报文结构如下图所示:

(1) 源、目标端口号字段:占 16 比特。 TCP 协议通过使用”端口”来标识源端和目标端的应用进程。端口号可以使用 0 到 65535 之间的任何数字。在收到服务请求时,操作系统动态地为客户端的应用程序分配端口号。在服务器端,每种服务在”众所周知的端口”( Well-Know Port)为用户提供服务。

(2) 序列号字段:占 32 比特。用来标识从 TCP 源端向 TCP 目标端发送的数据字节流,它表示在这个报文段中的第一个数据字节。

(3) 确认号字段:占 32 比特。只有 ACK 标志为 1 时,确认号字段才有效。它包含目标端所期望收到源端的下一个数据字节。

(4) 头部长度字段:占 4 比特。给出头部占 32 比特的数目。没有任何选项字段的 TCP 头部长度为 20 字节;最多可以有 60 字节的 TCP 头部。

(5) 标志位字段(U、 A、 P、 R、 S、 F):占 6 比特。各比特的含义如下:

① URG: 紧急指针有效。

② ACK: 为 1 时,确认序号有效。

③ PSH: 为 1 时,接收方应该尽快将这个报文段交给应用层。

④ RST: 为 1 时,重建连接。

⑤ SYN: 为 1 时,同步程序,发起一个连接。

⑥ FIN: 为 1 时,发送端完成任务,释放一个连接。

(6) 窗口大小字段:占 16 比特。此字段用来进行流量控制。单位为字节数,这个值是本机期望一次接收的字节数。

(7) TCP 校验和字段:占 16 比特。对整个 TCP 报文段,即 TCP 头部和 TCP 数据进行校验和计算,并由目标端进行验证。

(8) 紧急指针字段:占 16 比特。它是一个偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。

(9) 选项字段:占 32 比特。可能包括”窗口扩大因子”、”时间戳”等选项。

上述的内容讲解的是 TCP 首部信息,这些信息被封装在一个 IP 数据报中, 该数据报结构如下图所示。

 1.5 lwIP 的 TCP 报文首部数据结构

        实现 TCP 协议的文件有 tcp.h、 tcp.c、 tcp_in.c 和 tcp_out.c,这四个文件实现了 TCP 协议全部数据结构和函数, 其中 tcp.c 文件包含了与 TCP 编程、 TCP 定时器相关的函数,而tcp_in.c 文件包含了 TCP 报文段输入处理函数, 而 tcp_out.c 文件包含了 TCP 报文输出处理函数, 当然 tcp.h 定义了宏和结构体。 首先我们看一下 TCP 首部结构,这个结构为 tcp_hdr, 如下源码所示:

struct tcp_hdr {
PACK_STRUCT_FIELD(u16_t src); /* 源端口 */
PACK_STRUCT_FIELD(u16_t dest); /* 目的端口 */
PACK_STRUCT_FIELD(u32_t seqno); /* 序号 */
PACK_STRUCT_FIELD(u32_t ackno); /* 确认序号 */
PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); /* 首部长度+保留位+标志位 */
PACK_STRUCT_FIELD(u16_t wnd); /* 窗口大小 */
PACK_STRUCT_FIELD(u16_t chksum); /* 校验位 */
PACK_STRUCT_FIELD(u16_t urgp); /* 紧急指针 */
} PACK_STRUCT_STRUCT;

        可见, lwIP 使用 tcp_hdr 结构体描述 TCP 首部各个字段,值得注意的是,该结构体的_hdrlen_rsvd_flags 变量用来描述下图黄色部分的内容。

1.6 lwIP 的 TCP 连接状态图

发送端与接收端发送的指令会进入不同的状态, 因此, lwIP 在 tcpbase.h 文件中定义了枚举类型 tcp_state,它是用来描述 TCP 的状态,该枚举tcp_state 如下源码所示:

enum tcp_state {
CLOSED = 0, /* 关闭状态 */
LISTEN = 1, /* 监听状态 */
SYN_SENT = 2, /* 发送请求连接 */
SYN_RCVD = 3, /* 接收请求连接 */
ESTABLISHED = 4, /* 连接状态已建立 */
FIN_WAIT_1 = 5, /* 程序已关闭该连接 */
FIN_WAIT_2 = 6, /* 另一端已关闭连接 */
CLOSE_WAIT = 7, /* 等待程序关闭连接 */
CLOSING = 8, /* 两端同时收到对方的关闭请求 */
LAST_ACK = 9, /* 服务器等待对方接收关闭操作 */
TIME_WAIT = 10 /* 关闭成功 */
}

如果 TCP 需要建立连接,则系统需要三次握手;如果 TCP 中断连接,则系统需要四次挥手。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/18825.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL实战行转列(或称为PIVOT)实战sales的表记录了不同产品在不同月份的销售情况,进行输出

有一个sales的表,它记录了不同产品在不同月份的销售情况: productJanuaryFebruaryMarchProduct AJanuary10Product AFebruary20Product BJanuary5Product BFebruary15Product CJanuary8Product CFebruary12 客户需求展示为如下的样子: pro…

斯坦福报告解读4:图解有趣的推理基准(中)

《人工智能指数报告》由斯坦福大学、AI指数指导委员会及业内众多大佬Raymond Perrault、Erik Brynjolfsson 、James Manyika等人员和组织合著,该报告已被公认为最权威、最具信誉人工智能数据与洞察来源之一。 2024年版《人工智能指数报告》是迄今为止最为详尽的一份…

linux下常用的终端命令

文章目录 1. MV移动文件、重命名文件1.1 移动文件:mv [选项] 源文件或目录 目标文件或目录1.2 文件重命名 2. 查找:文件,内容,统计文件2.1 find查找文件2.2 Linux查找文件内容 3. 查看当前用户4. linux修改文件所属用户和组5. 复制…

Token验证流程、代码示例、优缺点和安全策略,一文告诉你。

Token和Session都是用于身份验证和授权的机制,而且Token渐渐成为主流,有不少小伙伴对token的认识不全,这里给大家分享下。 一、什么是Token Token是一种用于身份验证和授权的令牌,通常用于在客户端和服务器之间进行安全的通信。…

工程文档CAD转换必备!快速将 DWG 转换到 PNG ~

Aspose.CAD 是一个独立的类库,以加强Java应用程序处理和渲染CAD图纸,而不需要AutoCAD或任何其他渲染工作流程。该CAD类库允许将DWG, DWT, DWF, DWFX, IFC, PLT, DGN, OBJ, STL, IGES, CFF2文件、布局和图层高质量地转换为PDF和光栅图像格式。 Aspose AP…

gradio image 类型

3种类型,默认是 numpy.array numpy.array PIL.Image str file path. 互相转换 # 从路径到 numpy.ndarray import cv2 image_mask cv2.imread(imagePath) print(type(image_mask))# 从路径到 PIL.IMAGE from PIL import Image image_maskImage.open(imagePath) pri…

【Chrono Engine学习总结】6-创建自定义场景-6.1-3D场景获取

由于Chrono的官方教程在一些细节方面解释的并不清楚,自己做了一些尝试,做学习总结。 Chrono可以导入自定义的三维模型,所以想自己搭建一个3D仿真环境。过程中遇到了一些问题,记录与整理。 1、3D环境的创建方法 Chrono的Irrlich…

Llama 3-V: 比GPT4-V小100倍的SOTA

大模型技术论文不断,每个月总会新增上千篇。本专栏精选论文重点解读,主题还是围绕着行业实践和工程量产。若在某个环节出现卡点,可以回到大模型必备腔调重新阅读。而最新科技(Mamba,xLSTM,KAN)则提供了大模…

ECP5701 做为PD受电端取电sink芯片,可广泛应用在带锂电的终端设备上,例如电动工具,照明灯具,音箱设备,摄影设备,筋膜枪小家电等

随着科技的发展,USB-C接口逐渐成为手机、平板电脑、小型家电等新型电子设备的主流接口,相较于过去繁杂的传统接口,USB-C不仅简化了消费者的使用体验,也降低了制造商的生产成本。特别是随着PD协议的普及,Type-C接口因其…

设计以容错:应对失败的12种关键设计思想

"Design for Failure" 这一说法在产品设计、软件开发和系统架构中并不常见,因为它通常与追求成功和可靠性的目标相悖。然而,如果我们从另一个角度来理解它,即“设计以应对失败”或“设计以容错”,那么以下是12种常见的设…

mysql数据导入navicat中,报错提示1067

MySQL导入问题: 报错1067 - Invalid default value for 字段名 由于数据库版本升级,老数据库的数据文件导出以后,在新版本的数据库上执行会报错 这种问题多是由于默认值不兼容引起的,我们可以通过修改sql_mode来解决这个问题 由…

day17

第一题 本题可以采用快速排序的思想,适应随机数指定和三指针划分数组为三个区域的思想: 其中指针的移动细节如上题故事,如下所示: 当a区域的商都大于k时,我们要查找的k位置元素就在左区域,我们进一步在左区…

100个 Unity小游戏系列五 -Unity 抽奖游戏专题三老虎机游戏

一、演示效果 二、知识点讲解 2.1 布局 public void CreateItems(SlotsData[] slotsData){isInited false;slotsPrizeList new List<SlotsData>();for (int i 0; i < slotsData.Length; i){var item slotsData[i];slotsPrizeList.Add(item);}float bottomY -it…

学习sam的过程

一、抓包 我平时都是用花瓶去抓包的&#xff0c;配置也很简单。就是下载软件&#xff0c;然后一步步安装。下载地址&#xff1a;Download a Free Trial of Charles • Charles Web Debugging Proxy 。然后配置手机代理 对于那些走http协议的app是可以的&#xff0c;https的还是…

SAP锁机制(SAP Locks)经验小结

1. 数据一致性与锁 为什么要有锁机制&#xff1f;其背后的核心逻辑在于“保证数据的一致性”。 当数据被应用程序修改时&#xff0c;我们必须要保证修改后的数据具有一致性。在SAP系统中&#xff0c;将一致的数据状态从一个状态变动到另一个一致状态的时间跨度被称为LUW&…

应对意外断电:气膜建筑的安全防护与智能管理—轻空间

气膜建筑以其独特的结构和高效的建设方式&#xff0c;广泛应用于各类场馆、仓储设施和临时展馆。然而&#xff0c;当遇到意外断电导致气膜内部无法送风时&#xff0c;如何避免气膜倒塌&#xff0c;确保建筑安全呢&#xff1f; 断电应急响应 气膜建筑配备了先进的智能控制系统&a…

记录一次Redisson使用synchronized和分布式锁不生效的原因

最近在开发的过程中&#xff0c;遇到了一个并发场景&#xff0c;用户进行方案复制的时候&#xff0c;当快速点击两次操作的时候&#xff0c;出现了复制方案重名的情况&#xff0c;实际上是复制方案的方案名称&#xff0c;是由后端根据数据库已有的方案名称和当前要复制的方案名…

git新电脑下载配置记录

1、官网下载 2、安装 3、配置 &#xff08;1&#xff09;先生成密钥 ssh-keygen -t rsa -C “XXXqq.com” &#xff08;2&#xff09;生成两个文件&#xff0c;复制.pub,在GitHub的setting里面设置ssh&#xff0c; &#xff08;3&#xff09;验证远程是否配置成功 ssh -T g…

Python轻量级的插件框架库之pluginbase使用详解

概要 在软件开发中,插件系统是一个常见的需求。插件系统允许开发者动态加载和卸载功能模块,从而提高应用程序的灵活性和可扩展性。Python的pluginbase库是一个轻量级的插件框架,旨在简化插件系统的构建过程。pluginbase库提供了一套简单易用的API,使开发者能够快速集成插件…