【lwip】11-UDP协议&源码分析( 六 )


就是本地注销远端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层的接口函数 。上面的函数都是必须经过该函数实现的 。
    • 主要分析该函数 。其它函数看看就好了 。
11.12.1 udp_sendto_if_src():UDP发送数据基函数先分析UDP发送数据基函数 , 即是组装UDP报文的函数 。
然后再分析其它封装这个基函数的相关API 。
udp_sendto_if_src()