udp_port
累加管理 。
其初始值有两次初始:第一次是变量赋值,第二次是调用udp_init()
进行随机初始 。
变量初始值:
/* last local UDP port */static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START;
随机初始化:
- 需要开启LWIP随机宏
LWIP_RAND
。
/** * Initialize this module. */voidudp_init(void){#ifdef LWIP_RANDudp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND());#endif /* LWIP_RAND */}
11.10.3 udp_new_port()端口号申请端口号申请是有udp_port
进行累加,溢出就复位到UDP_LOCAL_PORT_RANGE_START
。/** * Allocate a new local UDP port. * * @return a new (free) local UDP port number */static u16_tudp_new_port(void){u16_t n = 0;struct udp_pcb *pcb;again:if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { /* 累加获取 */udp_port = UDP_LOCAL_PORT_RANGE_START; /* 溢出复位 */}/* Check all PCBs. */for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { /* 检查是否有重复 */if (pcb->local_port == udp_port) { /* 重复 */if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) {return 0; /* 如果所有端口号都重复了,返回申请失败 */}goto again; /* 重新申请 */}}return udp_port; /* 申请成功 */}
11.11 UDP控制块操作函数UDP控制块的操作函数相对简单,因为没有流量控制、没有确认机制等等 。11.11.1 udp_new():新建UDP控制块
udp_new()
:- 从
MEMP_UDP_PCB
内存池中获取UDP控制块资源 。 - 初始化部分字段 。
/** * @ingroup udp_raw * Creates a new UDP pcb which can be used for UDP communication. The * pcb is not active until it has either been bound to a local address * or connected to a remote address. * @see MEMP_NUM_UDP_PCB * * @return The UDP PCB which was created. NULL if the PCB data structure * could not be allocated. * * @see udp_remove() */struct udp_pcb *udp_new(void){struct udp_pcb *pcb;LWIP_ASSERT_CORE_LOCKED(); /* 内核锁确认 */pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); /* 申请UDP控制块资源 */if (pcb != NULL) {memset(pcb, 0, sizeof(struct udp_pcb));pcb->ttl = UDP_TTL; /* UDP数据出口默认的TTL值 */#if LWIP_MULTICAST_TX_OPTIONS /* 多播TX相关 */udp_set_multicast_ttl(pcb, UDP_TTL);#endif /* LWIP_MULTICAST_TX_OPTIONS */}return pcb;}
11.11.2 udp_remove():删除UDP控制块udp_remove()
:struct udp_pcb *pcb
:需要删除的UDP控制块 。
/** * @ingroup udp_raw * Removes and deallocates the pcb. * * @param pcb UDP PCB to be removed. The PCB is removed from the list of * UDP PCB's and the data structure is freed from memory. * * @see udp_new() */voidudp_remove(struct udp_pcb *pcb){struct udp_pcb *pcb2;LWIP_ASSERT_CORE_LOCKED(); /* 内核所内 */LWIP_ERROR("udp_remove: invalid pcb", pcb != NULL, return);mib2_udp_unbind(pcb);/* 先从udp_pcbs链表中移除 */if (udp_pcbs == pcb) {/* 如果当前UDP控制块是udp_pcbs的链表头 , 则直接更新链表头即可移除 */udp_pcbs = udp_pcbs->next;} else { /* 需要遍历udp_pcbs,把当前UDP控制块移除 */for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) {if (pcb2->next != NULL && pcb2->next == pcb) {pcb2->next = pcb->next;break;}}}/* 释放内存资源 */memp_free(MEMP_UDP_PCB, pcb);}
11.11.3 udp_bind():绑定控制块当UDP服务于应用程序时,数据流需要底层和应用层进行对接,就需要把UDP控制块绑定到本地IP和端口号 。绑定控制块时需要注意的是:
- 检查是否有PCB已经绑定了当前IP和端口号 。
- 当前PCB有没有已经插入了
udp_pcbs
链表 。
SOF_REUSEADDR
选项功能时 , 需要确保一个UDP报文最多只能到达一个应用程序 。即是一个网络接口中的一个端口号 。需要注意的是任意IP 。udp_bind()
:struct udp_pcb *pcb
:需要绑定本地IP和端口号的UDP控制块 。
ip_addr_t *ipaddr
:UDP控制块需要绑定的本地IP地址 。
- 如果为NULL,则绑定本地IP为全0的IP 。即表示本地任意IP都可 。
- 如果不为空,则绑定指定的本地IP 。
u16_t port
:UDP控制块需要绑定的本地端口号 。
- 如果为0,则绑定由内部调用
udp_new_port()
随机生成端口号 。 - 如果不为0,则绑定指定的端口号 。
- 如果为0,则绑定由内部调用
- 先检查下当前UDP控制块有没有插入了
udp_pcbs
链表,因为绑定成功后,需要插入该链表 。已经插入了 , 就不需要重复操作 。
- 检查绑定的IP地址 。传入为空,则赋值为全0的IP地址 。
- 检查绑定的端口号 。
推荐阅读
- 【什么是妖股】妖股是什么意思
- .net 温故知新:【9】.NET日志记录 ILogger使用和原理
- 【k8s连载系列】2. k8s整体架构
- 安卓手机截屏模式怎么设置(手机截屏模式怎么设置)
- ubantu18.04@Intel 82545EM 【安装文档】TRex流量分析仪保姆级安装指南--基于VMware虚拟机
- 星之彼端丹铜事件该如何选择
- iphone怎么刷机(iphone刷机教程)
- 《正义联盟》中超人是怎么死的
- 王者荣耀娜可露露前尘镜中文语音包怎么设置
- 《三国演义》中曹操的大将许褚是怎么死的(三国许褚做了哪些大事)