【LwIP源码学习3】TCP协议栈分析——数据接收流程

前言

本文介绍代码在lwip的tcp_in.c文件中,主要介绍TCP协议栈中数据的接收流程。

正文

1、一个正常的TCP数据,首先会传入到

tcp_input(struct pbuf *p, struct netif *inp)

函数,其中指针p指向传入的数据流。

2、从数据流中获取TCP头部

tcphdr = (struct tcp_hdr *)p->payload;

TCP头部数据结构为:
在这里插入图片描述
3、获取TCP头部中重要信息:

  tcphdr->src = lwip_ntohs(tcphdr->src);tcphdr->dest = lwip_ntohs(tcphdr->dest);seqno = tcphdr->seqno = lwip_ntohl(tcphdr->seqno);ackno = tcphdr->ackno = lwip_ntohl(tcphdr->ackno);tcphdr->wnd = lwip_ntohs(tcphdr->wnd);flags = TCPH_FLAGS(tcphdr);

seqno是序号,是发送方告诉接受方正在发送的报文段的序号。
ackno是确认号,是接收方告诉发送方已经接受到的最后一个报文段序号。
flags是6个控制位,其中的SYN与ACK在3次握手时使用如下:
在这里插入图片描述
客户端发起请求时,SYN为1,ACK为0。
服务器回复时,SYN为1,ACK为1。
客户端再次回复时,SYN为0,ACK为1。
ACK为0时,确认号无效(也就是ackno),建立连接后所有报文ACK置1。

flags中的FIN控制位置1,表示报文段的发送方数据已发送完毕,并要求释放运输连接。
释放TCP连接过程如下:
在这里插入图片描述

4、从 tcp_active_pcbs链表中寻找对应的pcb,寻找方式主要是看端口号和IP号是否能对应上:

if (pcb->remote_port == tcphdr->src &&pcb->local_port == tcphdr->dest &&ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) &&ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr()))

tcp_active_pcbs链表上的pcb都是正在等待接受数据或者发送数据的。

5、将输入数据流放到输入报文段里:

inseg.next = NULL;
inseg.len = p->tot_len;
inseg.p = p;
inseg.tcphdr = tcphdr;

因为lwip每次只处理一个输入数据流,所以输入报文段inseg是一个全局变量,同时也不会出现访问冲突。
报文段的管理如下:
在这里插入图片描述
tcp_active_pcbs链表上有很多活跃pcb,每个pcb有一个unsent指针和一个unacked指针,用于维护TCP协议中的发送窗口,unsent指向发送窗口中还未发送的报文段,unacked指向发送窗口中已经发送但是还没收到响应确认号的报文段。
发送窗口如下:
在这里插入图片描述

6、然后执行:

err = tcp_process(pcb);

进行TCP状态机处理。
TCP状态机转换过程如下:
在这里插入图片描述

7、一个已经建立连接的正常通信的pcb状态是ESTABLISHED
处理代码为:

case ESTABLISHED:tcp_receive(pcb);if (recv_flags & TF_GOT_FIN) { /* passive close */tcp_ack_now(pcb);pcb->state = CLOSE_WAIT;}break;

可以看到是调用tcp_receive()函数对输入数据做进一步处理。这时输入数据仍然在inseg输入报文段这个全局变量里。

8、接下来进入到tcp_receive()函数,首先根据新发送来TCP报文段中的窗口大小更新本pcb的发送窗口大小。

pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd);

9、查看接收到的报文段中显示的报文序号是否在接收窗口内:

if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt,pcb->rcv_nxt + pcb->rcv_wnd - 1)) 

pcb->rcv_nxt表示下一个要接收的报文序号。
pcb->rcv_wnd表示接收窗口大小。
其中pcb在初始化时,设置接收窗口大小代码如下:

pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND);

在lwipopts.h文件中设置

#define TCP_WND                         (2*TCP_MSS)
#define TCP_MSS                         (1500 - 40) 

也就是窗口大小为两个报文段。

10、查看接收到的报文段序号是否就是期望的序号:

      if (pcb->rcv_nxt == seqno) 

如果是则更新期望报文段序号:

pcb->rcv_nxt = seqno + tcplen;

把收到的数据放到全局变量recv_data里:

recv_data = inseg.p;

11、然后回到tcp_input()函数
首先判断是否接受到了数据:

if (recv_data != NULL)

有数据的话将数据传给应用层:

TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);

然后再试试能不能发点数据出去:

tcp_output(pcb);

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

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

相关文章

通过Express + Vue3从零构建一个用户认证与授权系统(二)数据库与后端项目搭建与实现

前言 上一篇完成了系统的相关设计文档的编写,本文将详细介绍如何一步步使用 TypeScript 和 Express 搭建一个模块化、类型安全的用户认证与授权系统,包括数据库设计、后端项目搭建、用户认证、角色与权限管理、错误处理以及 Swagger 文档集成。 项目准…

【ubuntu】ubuntu20.04安装cuda12.6与显卡驱动

目录 1.安装cuda12.6 2.安装显卡驱动 1.安装cuda12.6 https://developer.nvidia.com/cuda-toolkit-archive https://developer.nvidia.com/cuda-12-6-0-download-archive?target_osLinux&target_archx86_64&DistributionUbuntu&target_version20.04&target_…

DART: Implicit Doppler Tomography for Radar Novel View Synthesis 笔记

Link:https://wiselabcmu.github.io/dart/ Publish: 2024CVPR Abstract DART主要任务就是用来合成雷达距离多普勒图像range-droppler,可用于生成高质量的断层扫描图像。 Related Work 1 Radar Simulation 基于模型的方法 任务&#xff…

XGBoost回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出

回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出 目录 回归预测 | MATLAB实现XGBoost极限梯度提升树多输入单输出预测效果基本介绍模型描述程序设计参考资料预测效果 基本介绍 XGBoost的全称是eXtreme Gradient Boosting,它是经过优化的分布式梯度提升库,旨在高效、…

医学和生信web APP 平台- Appmatrix

医学(和生信)web APP 平台- Appmatrix 最近使用shinyproxy将平时所构建的shiny和streamlit医学类应用汇集在一起,实现一站式访问,另外,使用了自己电脑内网穿透,一定程度上缓解了数据分析类APP消耗计算资源…

关闭线程池的API介绍

线程池关闭主要涉及以下几个API: shutdown:关闭线程池,此方法执行后,线程池不会立即关闭,1、等待正在执行的线程任务执行完毕 2、等待任务队列中的任务执行完毕,步骤1和2执行后,线程池才完全中止isShutdown:判断线程池…

PostgreSQL学习笔记六:模式SCHEMA

模式(Schema) PostgreSQL中的模式(Schema)是一个命名的数据库对象集合,包括表、视图、索引、数据类型、函数、存储过程和操作符等。模式的主要作用是组织和命名空间数据库对象,使得同一个数据库中可以包含…

C/C++语言基础--C++异常看这一篇就够了

本专栏目的 更新C/C的基础语法,包括C的一些新特性 前言 通过前面几节课,我们学习了抽象、封装、继承、多态等相关的概念,接下来我们将讲解异常,异常是专门处理错误的;这一次加了不少图标,希望大家喜欢;C语…

牛客周赛 Round 63(构造、组合数、线性基)

文章目录 牛客周赛 Round 63(构造、组合数、线性基)A. 小红的好数B. 小红的好数组C. 小红的矩阵行走(简单思维题)D. 小红的行列式构造(构造、数学题)E. 小红的 red 计数(组合数)F. 小红开灯(线性基) 牛客周赛 Round 63(构造、组合数、线性基) A. 小红的好数 按照题意判断即可…

QT事件与网络通信

闹钟 头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QTimer> #include <QTextToSpeech> // 添加此行以引入QTextToSpeech类QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACEclass MainWin…

Python基础语法条件

注释 注释的作用 通过用自己熟悉的语言&#xff0c;在程序中对某些代码进行标注说明&#xff0c;这就是注释的作用&#xff0c;能够大大增强程序的可读性。 注释的分类及语法 注释分为两类&#xff1a;单行注释 和 多行注释。 单行注释 只能注释一行内容&#xff0c;语法如下…

基于springboot管理系统

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

B3622 枚举子集

1. 注意dfs内&#xff0c;for循环的遍历&#xff0c;想清楚把什么赋值给a[x] 2.本题只需要把0或1赋值给a[x]所以 #include<bits/stdc.h> using namespace std; int n; int a[20]; int vis[20]; void pr() {for (int i 1; i < n; i) {if (a[i] 0)cout << N;els…

Flink On kubernetes

Apache Flink 是一个分布式流处理引擎&#xff0c;它提供了丰富且易用的API来处理有状态的流处理应用&#xff0c;并且在支持容错的前提下&#xff0c;高效、大规模的运行此类应用。通过支持事件时间&#xff08;event-time&#xff09;、计算状态&#xff08;state&#xff09…

网络分析仪——提升网络性能的关键工具

目录 什么是网络分析仪&#xff1f; 1. 实时流量监控 2. 历史数据回溯分析 3. 网络性能关键指标监测 4. 可视化界面与报告生成 总结 在当今的数字化世界&#xff0c;网络的稳定性和性能直接影响企业的运营效率。网络拥堵、延迟和丢包等问题会导致用户体验的下降&#xff…

Linux常用功能整合

Linux Linux 前言一、常用操作以及概念 快捷键求助关机PATHsudo包管理工具发行版VIM 三个模式GNU开源协议 二、磁盘 磁盘接口磁盘的文件名 三、分区 分区表开机检测程序 四、文件系统 分区与文件系统组成文件读取磁盘碎片blockinode目录日志挂载目录配置 五、文件 文件属性文件…

银行卡基础信息查询 API 对接说明

本文将介绍一种 银行卡基础信息查询 API 对接说明&#xff0c;它可用于银行卡基础信息查询。 接下来介绍下 银行卡基础信息查询 API 的对接说明。 申请流程 要使用 API&#xff0c;需要先到 银行卡基础信息查询 API 对应页面申请对应的服务&#xff0c;进入页面之后&#xf…

服务器系统克隆技术

工作任务&#xff1a;克隆对象是Windows server2019 和2022的datacenter版本 条件&#xff1a;在已经完成安装的虚拟机上做克隆 图1-1 用两个服务器的母盘准备进行克隆 第一步&#xff1a;新建一个文件目录用于安放克隆好的服务器 图1-2 创建两个目录用于安放即将克隆好的服务…

Axure科技感元件:打造可视化大屏设计的得力助手

Axure&#xff0c;作为一款专业的原型设计工具&#xff0c;凭借其强大的设计功能、丰富的组件库和灵活的交互能力&#xff0c;成为了许多设计师打造科技感设计的首选工具。其中&#xff0c;Axure科技感元件更是以其独特的魅力和实用性&#xff0c;在数据可视化大屏、登录界面、…

python画图|在三维空间的不同平面上分别绘制不同类型二维图

【1】引言 前序已经完成了基础的二维图和三维图绘制教程探索&#xff0c;可直达的链接包括但不限于&#xff1a; python画图|3D参数化图形输出-CSDN博客 python画三角函数图|小白入门级教程_正余弦函数画图python-CSDN博客 在学习过程中&#xff0c;发现一个案例&#xff1…