lwIP 没有实现UDP的分片机制。这里需要注意。
- UDP header struct
struct udp_hdr {
u16_t src;
u16_t dest;
u16_t len;
u16_t chksum;
};
- 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 *.*
阅读(3083) | 评论(1) | 转发(0) |