就是本地注销远端IP和远端端口号的绑定 。
udp_disconnect()
:
- 重置UDP控制块远端IP和远端端口号字段 。
- 解绑本地网卡 。
- 标记UDP控制块为未连接 。
/** * @ingroup udp_raw * Remove the remote end of the pcb. This function does not generate * any network traffic, but only removes the remote address of the pcb. * * @param pcb the udp pcb to disconnect. */voidudp_disconnect(struct udp_pcb *pcb){LWIP_ASSERT_CORE_LOCKED();LWIP_ERROR("udp_disconnect: invalid pcb", pcb != NULL, return);/* 重置远端IP */#if LWIP_IPV4 && LWIP_IPV6if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) {ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE);} else {#endifip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip);#if LWIP_IPV4 && LWIP_IPV6}#endif/* 重置远端端口号 */pcb->remote_port = 0;/* 解绑本地网卡 */pcb->netif_idx = NETIF_NO_INDEX;/* 标记PCB为未连接 */udp_clear_flags(pcb, UDP_FLAGS_CONNECTED);}
11.11.7 udp_recv():控制块注册接收函数udp_recv()
只是用于UDP控制块注册接收函数 。【【lwip】11-UDP协议&源码分析】
/** * @ingroup udp_raw * Set a receive callback for a UDP PCB. * This callback will be called when receiving a datagram for the pcb. * * @param pcb the pcb for which to set the recv callback * @param recv function pointer of the callback function * @param recv_arg additional argument to pass to the callback function */voidudp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg){LWIP_ASSERT_CORE_LOCKED();LWIP_ERROR("udp_recv: invalid pcb", pcb != NULL, return);/* remember recv() callback and user data */pcb->recv = recv;pcb->recv_arg = recv_arg;}
11.11.8 udp_netif_ip_addr_changed():更新UDP控制块本地IP当底层网卡在IP层的IP有所更新时,需要把UDP控制块中本地IP绑定就的IP也更新 。即是当IP地址改变时,将从netif.c调用此函数检查并更新 。
udp_netif_ip_addr_changed()
:ip_addr_t *old_addr
:旧IP 。ip_addr_t *new_addr
:新IP 。- 检索LWIP中UDP控制块链表
udp_pcbs
,把绑定就的IP更新到新的IP去 。
/** This function is called from netif.c when address is changed * * @param old_addr IP address of the netif before change * @param new_addr IP address of the netif after change */void udp_netif_ip_addr_changed(const ip_addr_t *old_addr, const ip_addr_t *new_addr){struct udp_pcb *upcb;if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) { /* 新旧IP不一致才有意义 */for (upcb = udp_pcbs; upcb != NULL; upcb = upcb->next) { /* 检索所有已激活的UDP控制块 */if (ip_addr_eq(&upcb->local_ip, old_addr)) { /* 找到绑定需要更新IP的UDP控制块 */ip_addr_copy(upcb->local_ip, *new_addr); /* 更新 */}}}}
11.12 UDP发送数据注意校验和相关宏:LWIP_CHECKSUM_ON_COPY
:在支持使用数据区已经计算好的UDP数据区校验和 。CHECKSUM_GEN_UDP
:在软件中生成出UDP数据包的校验和 。
udp_send()
:UDP RAW的接口,需要的参数只需要UDP和用户数据即可 。
udp_sendto()
:UDP RAW的接口,对比上面函数 , 可以指定远端IP和与远端端口号 。
udp_sendto_if()
:UDP RAW的接口 , 对比上面udp_sendto()
函数,该函数还能指定网卡 。
udp_sendto_if_src()
:UDP RAW的接口,也是UDP发送数据的基函数,是实现组装UDP包 , 和转交到IP层的接口函数 。上面的函数都是必须经过该函数实现的 。
- 主要分析该函数 。其它函数看看就好了 。
然后再分析其它封装这个基函数的相关API 。
udp_sendto_if_src()
:struct udp_pcb *pcb
:负责本次数据交互的UDP控制块 。struct pbuf *p
:需要发送的数据的pbuf 。ip_addr_t *dst_ip
:远端IP 。u16_t dst_port
:远端端口号 。struct netif *netif
:本地网卡,即是发送本次UDP报文的网络接口 。ip_addr_t *src_ip
:源IP地址 。- 检查传入的参数是否异常 。
- 检查当前UDP控制块有没有绑定了本地IP(包括任意IP)和本地端口号 。还没绑定就需要调用
udp_bind()
进行绑定 。 - 预测检查UDP报文长度:UDP数据区追加UDP首部后是否溢出,溢出丢弃 。
- 检查pbuf长度能否扩充到链路层报文:不能就申请多一个pbuf q,包含么UDP首部+IP首部+链路层首部 , 然后拼接到当前pbuf,让其拥有足够空间 。
推荐阅读
- 【什么是妖股】妖股是什么意思
- .net 温故知新:【9】.NET日志记录 ILogger使用和原理
- 【k8s连载系列】2. k8s整体架构
- 安卓手机截屏模式怎么设置(手机截屏模式怎么设置)
- ubantu18.04@Intel 82545EM 【安装文档】TRex流量分析仪保姆级安装指南--基于VMware虚拟机
- 星之彼端丹铜事件该如何选择
- iphone怎么刷机(iphone刷机教程)
- 《正义联盟》中超人是怎么死的
- 王者荣耀娜可露露前尘镜中文语音包怎么设置
- 《三国演义》中曹操的大将许褚是怎么死的(三国许褚做了哪些大事)