LWIP UDP 编程

2023-11-06

一、udp.c实现的函数

1、void udp_input(struct pbuf *p, struct netif *inp)

说明:处理接收到的udp数据包。

参数:p数据包缓存区;inp网络接口。

   

2、err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)

说明:发送udp包。这个函数直接调用udp_sendto()函数。

参数:pcb协议控制块;p数据包发送缓存区。

返回:ERR_OK发送成功;ERR_MEM发送溢出;ERR_RTE不能发送到指定ip;其它表示发送失败。

   

3、err_t udp_sendto(struct udp_pcb *pcb, struct pbuf *p, 
                    struct ip_addr *dst_ip, u16_t dst_port)

说明:发送udp包到指定ip地址。

参数:pcb协议控制块;p数据包发送缓存区;dst_ip目的ip地址;dst_port目的端口号。

   

4、err_t udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, 
                       struct ip_addr *dst_ip, u16_t dst_port, struct netif *netif)

说明:按照指定的网络接口和ip地址发送udp包。

参数:pcb协议控制块;p数据包发送缓存区;dest_ip目的ip地址;dst_port目的端口号,netif网络接口。

   

5、err_t udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)

说明:在协议控制块中绑定本地ip地址和本地端口号

参数:pcb协议控制块;ipaddr本地ip地址;port本地端口号。

返回:ERR_OK成功;ERR_USE已经被占用。

   

6、err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)

说明:与远端udp主机建立连接。

参数:pcb所需连接的协议控制块;ipaddr远端ip地址;port远端端口号。

   

7、void udp_disconnect(struct udp_pcb *pcb)

说明:断开指定连接。

参数:pcb所需断开连接的协议控制块。

   

8、void udp_recv(struct udp_pcb *pcb, 
                 void (* recv)(void *arg, struct udp_pcb *upcb, struct pbuf *p,
                               struct ip_addr *addr, u16_t port),
                 void *rev_arg)

说明:设置接收到数据包时调用的回调函数及其参数。

参数:pcb协议控制块;recv回调函数名(地址);rev_arg回调函数参数。

这个函数直接修改pcb->recv和pcb->recv_arg的值。

   

9、void udp_remove(struct udp_pcb *pcb)

说明:删除指定udp协议控制块,从协议控制链表中删除并释放内存资源。

参数:pcb所要删除的协议控制块。

   

10、struct udp_pcb * udp_new(void)

说明:创建udp协议控制块,并不分配资源。

返回:协议控制块指针,指向NULL。


- UDP functions

err_t udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
函数遍历整个UDP PCB链表,以排除在没有设置REUSE_ADDR或者REUSE_PORT标志的情况下绑定到一个以相同port绑定的pcb或者以相同port及ip绑定的pcb。如果需要绑定的port无效,则分配最小可用port。如果该pcb未在原来PCB链表中,则加入链表。具体流程参看流程图。
err_t udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
连接到远程端口。如果还未分配本地port,则分配一个空闲port。然后将一下两种地址绑定类型进行转换:
a. *.local_port  foreign_ip.foreign_port: 调用ip_router确定本地ip。
b. *.*  *.foreign_port: 转换为 *.local_port  *.foreign_port

err_t udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
struct ip_addr *dst_ip, u16_t dst_port)

该函数借用当前的pcb调用udp_send发送UDP包,完成后,回复原来pcb内容。

err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
如果pcb未绑定,则调用udp_bind获取一个可用的port绑定之。然后构造UDP包,查找能够到达remote_ip的router接口,如果有必要,将该接口的本地ip作为UDP的src ip。如果UDP需要校验和,则调用inet_chksum_pseudo函数,计算校验和。最后调用ip_output_if将UDP包传送到下层IP层发送。

void udp_input(struct pbuf *p, struct netif *inp)
该函数接受来自ip层的UDP包。将所有PCB都遍历,如果有多个绑定,则给每一个进程复制一份数据报,实际调用pcb->recv()。
其中的数据报的地址绑定匹配优先级和协议上的略有区别:
    Local                            Foreign
local_ip(*).local_port  foreign_ip(*).foreign_port

local_ip(*).local_port  *.*

UDP发送过程:

1.应用层:绑定UDP套接字
我们必须先创建一个UDP套接字,通过调用udp_new()进行申请

然后调用udp_bind()绑定在UDP端口上。在这个调用过程中,我们必须编写一个用于处理这个UDP套接字接收到的数据报文的函数,并把这个函数作为udp_bind()的参数,以后当套接字接收到数据报文时会自动调用这个函数,我们将在后面介绍这个函数怎么调用的。

绑定结束之后,必须调用udp_connect()将数据报文的目的地址绑定在UDP的数据结构中,最后就是调用udp_send()把数据报文发送出去。

 udp_bind()的处理流程图


2.传输层的处理
做好应用层的处理之后,数据报文被提交到UDP层,udp_send()函数中首先给数据报文加入UDP头部,然后调用ip_route()选择一个合适的网络接口进行发送,最后调用ip_output()把数据报文传入IP层。

3.IP层的处理
ip_route()函数比较各个网络接口的IP地址是否与目的IP地址在同一子网中,如果有,就把它当成发送的网络接口返回,如果没有就返回一个默认的网络接口。
在ip_output()函数中,先给数据报文加上IP头部,然后比较目的IP地址与网络接口的IP地址是否在同一网段,如果不是,就必须先把数据报文发送到网关,于是使用网关的IP地址作为目的主机,如果目的IP地址与网络接口的IP地址在同一网段,则把目的IP地址作为目的主机。接着调用arp_lookup()在ARP缓存中查找目的主机的MAC地址,找到了调用ethernet_output()把数据报文传入到数据链路层发送,如果找不到,就调用arp_query()发送ARP请求解析目的主机的MAC地址。

4.ARP协议的处理
arp_lookup()实现在本地ARP缓存中查找目的主机的MAC地址,找到了返回该MAC地址,找不到返回NULL。
arp_query()函数中构造一个ARP请求报文,然后调用ethernet_output()把该报文送到数据链路层发送。

5. 数据链路层的处理
数据链路层的处理就是给数据报文添上相对的以太网头部,然后调用lowlever_output()直接把报文传送出去。


UDP接收过程:

接收过程与发送过程刚好相反:

数据报文首先调用ethernet_input()函数到达数据链路层,去掉以太网头部之后如果是ARP报文传给调用arp_input()交给ARP协议处理,如果是IP报文就调用ip_input()进入IP层处理。

ip_input()函数中比较数据报文的目的IP地址,如果与某个网络接口的IP地址相同,则接收这个报文,依照IP头部的协议字段,调用各自协议的输入处理函数,本例中将调用udp_input()。

在udp_input()中提取数据报文的端口号,然后在已登记的套接字中查找与该端口号符合的UDP接收函数,如果没有找到相应的套接字,调用icmp_output()发送一个ICMP不可达报文,如果找到了,就调用该函数(这个函数就是我们在udp_bind()时传入的其中一个参数)。

udp_input处理流程图:



http://blog.chinaunix.net/uid-26611973-id-3181142.html

http://blog.csdn.net/zyboy2000/article/details/4297638


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LWIP UDP 编程 的相关文章

  • Linux系统中如何查看TCP连接数

    这篇文章主要为大家展示了 Linux系统中如何查看TCP连接数 内容简而易懂 条理清晰 希望能够帮助大家解决疑惑 下面让小编带领大家一起研究并学习一下 Linux系统中如何查看TCP连接数 这篇文章吧 一 查看哪些IP连接本机 netsta
  • raid配置ssd为缓存_群晖SSD缓存有什么用?

    作用 SSD 缓存功能 使用户可以通过添加 SSD 提高 Synology NAS 上的随机访问性能 功能模式 只读缓存 使用此类型的 SSD 缓存时 只会将经常访问的数据存储在 SSD 缓存中以提高随机读取速度 因为 SSD 不涉及任何数
  • stm32 IAP APP 相互跳转实验 (keil4 jlink STM32F407ZE)

    1 实验目标 STM32 IAP学习时 希望有一个快捷的方式去实验IAP与APP之间的相互跳转 1 验证IAP跳转至APP 2 验证APP通过软件reset跳转至IAP 避免再一开始就实验完整的IAP过程 编写BootLoader 编写 A
  • flutter 高德地图 amap_flutter_location 隐私合规校验失败

    flutter 高德地图 amap flutter location 隐私合规校验失败 提醒 ios版本他的最新库是没有办法使用的 如果你的项目需要使用到iOS版本 请使用下面的路径 https github com yangsiyi41
  • 微信开发(js-sdk)中遇见的各种问题

    微信开发的准备工作 不熟 不是我来搞的 copy一下别人和官方的 1 绑定域名 先登录微信公众平台进入 公众号设置 的 功能设置 里填写 JS接口安全域名 备注 登录后可在 开发者中心 查看对应的接口权限 2 引入js文件 在需要调用JS接
  • 动态路由协议RIP配置实战

    1 RIP简介 RIP是一种基于距离矢量 Distance Vector 算法的协议 它使用跳数 Hop Count 作为度量值来衡量到达目的地址的距离 在RIP网络中 RIP协议要求网络中每一台路由器都要维护从自身到每一个目的网络的路由信
  • Kettle-动态数据链接,使JOB得以复用

    动态数据连接 使JOB得以复用 背景 移动执法系统在目前的主要的部署策略为1 N的方式 即总队部署一套 地市各部署一套 且基本都在环保专网 各地市的业务数据需要推送到总队系统 以便总队系统做整体的监督 决策 在整个数据对接过程中 基于Ket
  • Matlab导入txt文件

    有三种常见的方式 1 A importdata filename txt 则A就是n m的矩阵了 2 load filename txt 这样也是载入n m的矩阵 3 在MATLAB的work文件夹下 选择想要导入的数据 用右键import
  • 前端系列-1 HTML+JS+CSS基础

    背景 前端系列会收集碎片化的前端知识点 作为自己工作和学习时的字典 欢迎读者收藏和使用 笔者是后端开发 前端涉猎不深 因此文章重在广度和实用 对原理和性能不会过多深究 1 html 1 1 html5网页结构
  • 如何判断两条线段是否相交

    本篇是在 C 笔记 如何判断2个线段相交 的基础上加上自己的理解和实践总结出的判断两线段是否相交的方法 判断两条线段是否相交 先附上判断函数 bool judge int Ax1 int Ay1 int Ax2 int Ay2 int Bx
  • vue3的ref,unref,reactive,toRefs,toRef

    ref函数 接受一个初始值并返回一个响应式且可变的 ref 对象 ref 对象仅有一个 value属性 指向该初始值 const count ref 0 console log count value 0 count value conso
  • 判断图连通性的三种方法

    在看哥尼斯堡七桥问题的时候 谈到欧拉回路的问题 不免又想到了图的连通性 想到以后说不定会遇到相关问题 就做下连通性判断算法总结实现 如果一个图是连通的 那么从一个节点开始访问 采用深度优先或者广度优先对它进行遍历 那么必定能够访问完所有的节
  • xml转JavaBean

    在进行webservice通信的时候 需要解析xml为一个对象 由于个人也是第一次接触xml转对象 于是参考网上的例子写了一个工具类 所有jar包支持 fastjson dom4j public class XmlConverBeanUti
  • 数字化转型:科技赋能供给创造需求 附下载

    疫情对各行业及科创的影响我们都深切地感受到了 像AI家居 AR游戏等比较火爆的项目都是在疫情中喷发 此报告结合疫情驱动新兴技术演变及商业落地的态势 探讨数字化对于科创的意义 报告亮点 5G商业化将伴随成熟应用由点向面展开 人工智能和企业数字

随机推荐

  • 06-底层必备源码-JVM底层-GC算法流程(自我总结)

    一 判断 是否GC 的算法 1 引用计数法 1 1 规则 如果这个obj被引用 计数器 1 引用失效 计数器 1 当一个obj的引用计数器为0 就不代表被使用 1 2 缺点 不能解决循环引用的问题 2 可达性分析算法 2 1 规则 以GCr
  • Keras CIFAR-10图像识别数据集 2021-07-10

    Keras CIFAR 10图像识别数据集 一 下载CIFAR 10数据 1 导入所需模块 from keras datasets import cifar10 import numpy as np np random seed 10 2
  • 万事开头难——Android SDK安装

    首届 Google 暑期大学生博客分享大赛 2010 Andriod 篇 今天研究了一上午才把SDK安装成功 真是万事开头难 下面就把安装的过程分享出来 Eclipse Android SDK 2 1环境部署 一 第一步安装JDK Java
  • t检验与Z检验的区别

    在统计学中 假设检验是评估某种特定情况下观察到的数据是否符合假设的一种方法 t检验和Z检验是两种常用的假设检验方法 分别用于比较均值差异以及比例差异 在医学统计中 t检验和Z检验经常被用于研究和比较不同治疗方法的效果 例如药物疗效 手术效果
  • spring JavaBean引入JavaBean ( 外部引用, 内部定义, 级联属性 )

  • 探针漏洞_长亭xray:一款自动化Web漏洞扫描神器(免费社区版)

    xray 简介 xray 是从长亭洞鉴核心引擎中提取出的社区版漏洞扫描神器 支持主动 被动多种扫描方式 自备盲打平台 可以灵活定义 POC 功能丰富 调用简单 支持 Windows macOS Linux 多种操作系统 可以满足广大安全从业
  • java删除指定目录下的文件(包括目录)

    代码 import java io File public class Test 判断指定的文件或文件夹删除是否成功 param FileName 文件或文件夹的路径 return true or false 成功返回true 失败返回fa
  • 网络综合布线实训室方案(2023版)

    综合布线实训室概述 随着智慧城市的蓬勃发展 人工智能 物联网 云计算 大数据等新兴行业也随之崛起 网络布线系统作为现代智慧城市 智慧社区 智能建筑 智能家居 智能工厂和现代服务业的基础设施和神经网络 发挥着重要作用 实践表明 网络系统故障的
  • 使用web3 部署智能合约

    CentOS 7 环境 web3安装 及 对象的创建 m0 47233175的博客 CSDN博客https blog csdn net m0 47233175 article details 121960931还未安装web3环境 请参照以
  • 《OpenGL ES 2.0 Programming Guide》摘录

    一 Introduction toOpenGL ES 2 0 1 What Is OpenGL ES OpenGL ES is an application programming interface API for advanced 3D
  • JPA中所有findBy语法规则(举例)

    JPA中findBy基本语法规则 1 首先先新建一个数据库 名字叫做jpatest 2 新建一个SpringBoot项目 如果新手还不会 请先阅读idea中如何快速创建SpringBoot项目 这边需要引入jpa mysql web的相关依
  • 深刻理解Linux进程间通信(IPC)

    http www cnblogs com andtt articles 2136279 html 0 序 1 管道 1 1 管道概述及相关API应用 1 2 有名管道概述及相关API应用 1 3 小结 1 4 参考资料 2 信号 上 2 1
  • 详解DenseNet(密集连接的卷积网络)

    前言 在计算机视觉领域 卷积神经网络 CNN 已经成为最主流的方法 比如最近的GoogLenet VGG 19 Incepetion等模型 CNN史上的一个里程碑事件是ResNet模型的出现 ResNet可以训练出更深的CNN模型 从而实现
  • C++中enum的大小

    关于枚举类型所占内存的大小 书里对枚举大小的定义是 sizeof枚举是sizeof某类可以包含枚举range的整型 并且不会大于sizeof int 也就是说枚举大小不一定等于sizeof int 转载请尊重原创 保留相关链接本文来自多宝平
  • MySQL限制数据的小数位数——DECIMAL类型

    DECIMAL简介 DECIMAL从MySQL 5 1引入 列的声明语法是DECIMAL M D NUMERIC与DECIMAL同义 如果字段类型定义为NUMERIC 则将自动转成DECIMAL 对于声明语法DECIMAL M D 自变量的
  • 蓝斯登定律(转载)

    给员工快乐的工作环境 蓝斯登定律 给员工快乐的工作环境 跟一位朋友一起工作 远较在父亲之下工作有趣得多 提出者 美国管理学家蓝斯登 点评 可敬不可亲 终难敬 有权没有威 常失权 编辑 从案例中体会蓝斯登定律 连续20年保持赢利的美国西南航空
  • 机器学习特征工程

    特征工程 目录 特征工程 1 数据预处理 1 1数据无量纲化 1 2缺失值处理 1 3处理分类型特征 编码与哑变量 1 4处理连续型特征 二值化与分段 1 5数据变换 总结 2 特征选择 2 1 Filter 2 1 1 方差选择法 2 1
  • Qt Creator打开CMake管理的Quick工程,并调试qml

    文章目录 前言 一 需求背景 二 遇到的问题 三 解决方案 四 Demo 提示 以下是本篇文章正文内容 下面案例可供参考 一 需求背景 1 需要对Qml程序进行调试 2 用CMake管理工程文件 3 能用Qt Creator或者VS进行开发
  • 数据库之postgresql库锁表解锁

    1 检索出死锁进程的ID SELECT FROM pg stat activity WHERE datname 死锁的数据库ID 检索出来的字段中 wating 字段 数据为t的那条 就是死锁的进程 找到对应的 procpid 列的值 2
  • LWIP UDP 编程

    一 udp c实现的函数 1 void udp input struct pbuf p struct netif inp 说明 处理接收到的udp数据包 参数 p数据包缓存区 inp网络接口 2 err t udp send struct