LWIP UDP 编程
一、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
</div>
LWIP UDP 编程相关推荐
- [C# 网络编程系列]专题七:UDP编程补充——UDP广播程序的实现
上次因为时间的关系,所以把上一个专题遗留下的一个问题在本专题中和大家分享下,本专题主要介绍下如何实现UDP广播的程序,下面就直接介绍实现过程和代码以及运行的结果. 一.程序实现 UDP广播程序的实现代 ...
- [C# 网络编程系列]专题六:UDP编程
引言: 前一个专题简单介绍了TCP编程的一些知识,UDP与TCP地位相当的另一个传输层协议,它也是当下流行的很多主流网络应用(例如QQ.MSN和Skype等一些即时通信软件传输层都是应用UDP协议的) ...
- Java刷题知识点之TCP、UDP、TCP和UDP的区别、socket、TCP编程的客户端一般步骤、TCP编程的服务器端一般步骤、UDP编程的客户端一般步骤、UDP编程的服务器端一般步骤...
TCP和UDP是两个传输层协议,广泛应用于网络中不同主机之间传输数据.对任何程序员来说,熟悉TCP和UDP的工作方式都是至关重要的.这就是为什么TCP和UDP是一个流行的Java编程面试问题. Jav ...
- 穿透Socks5 代理的UDP编程
网络编程中,对于数据传输实时性要求较高的场合,大家都会选择UDP来作为数据传输协议,在TCP/IP协议族中UDP协议较TCP协议需要的网络系统资源更少.然而在企业应用中,由于网络安全原因等会导致除了特 ...
- TCP/UDP编程中的问题汇总
TCP/UDP编程中的问题汇总 TCP和UDP发送大文件的问题. 答: 发送端: 发送时,先发送文件的名称及大小等信息. 然后,设置一个缓冲区的大小,假设为4K. 再循环读4K的文件内容,并发送,直到 ...
- Java UDP 编程简介.
一.UDP 协议简介 UPD协议 是常见的 网络传输协议之一, 当然另1个是TCP协议. UPD协议 是一种不靠的协议. 是因为发送方不会关心接受方的状态, 直接向接收方发送数据包, 也就是说这个数据 ...
- Qt学习笔记之UDP编程
1. UDP概述 UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中 ...
- 【Linux网络编程】UDP编程
00. 目录 文章目录 00. 目录 01. 概述 02. UDP编程C/S结构 03. UDP常用函数 3.1 sendto函数 3.2 recvfrom函数 3.3 bind函数 04. 程序示例 ...
- python的基础网络编程是下列_Python入门基础之网络编程、socket编程、TCP、UDP编程...
忙了两天,继续更文!希望多多支持. 套接字 套接字是一种具有之前所说的"通讯端点"概念的计算机网络数据结构.网络化的应用程序在开始任何通讯之前都必需要创建套接字. 套接字有三种: ...
最新文章
- python selenium 下拉列表_从下拉列表中选择python selenium选项
- tf卡测试软件_真正的白菜价?1G不到1元,铠侠(原东芝存储)microSD卡评测
- [Python] L1-024. 后天-PAT团体程序设计天梯赛GPLT
- asp.net在ie7中使用FileUpload上传前预览图片
- Java并发 stop()、resume()和suspend()
- array(numpy) 的size 和Image(PIL) 的shape比较
- 华为认证的好处是什么?考试费是多少?
- 记忆力:魔方基础教程
- 蚂蚁金服校招一面有感
- datatables实现复选框全选反选!!(亲测有效)
- Some/IP和DoIP有什么区别?
- 如何将本地代码同步到Gitee(码云)
- 程序员2年苦心积攒学习资料【下载】
- Autodesk所有产品的卸载、安装解决方案(3dsmax、cad等)
- 给技术管理者的10个锦囊
- 千牛客服面板插件开发
- Visual Basic编程语言简介
- 一只兔子吃掉了狼和野猪
- java map去重_用map集合去重汇总
- iHPS-3300型 超高频局放监测及温升在线监测装置
热门文章
- 女人应该每天都写日记
- WEB前端学习——第六次作业(banner图片左右切换按钮)
- 第十四周项目二成绩姓名排名
- python应用情景
- asp毕业设计—— 基于asp+access的课程教学网站设计与实现(毕业论文+程序源码)——教学网站
- Solidity 构造函数的理解
- leetcode26 删除排序数组中的重复项 python
- 2023版D盾防火墙v2.1.7.2,主动防御保护,以内外保护的方式 防止网站和服务器给入侵。限制了常见的入侵方法,让服务器更安全
- 清华大学谭浩强c语言PPT,C语言课件清华大学谭浩强版.ppt
- 语音合成(speech synthesis)方向一:双重学习Dual Learning