14. UDP协议 您所在的位置:网站首页 udp使用 14. UDP协议

14. UDP协议

#14. UDP协议 | 来源: 网络整理| 查看: 265

14.4.2. UDP控制块¶

与TCP协议一样,为了更好管理UDP报文,LwIP定义了一个UDP控制块,记录与UDP通信的所有信息, 如源端口号、目标端口号、源IP地址、目标IP地址以及收到数据时候的回调函数等等, 系统会为每一个基于UDP协议的应用线程创建一个UDP控制块,并且将其与对应的端口绑定,这样子就能进行UDP通信了。 与TCP协议一样,LwIP会把多个这样子的UDP控制块用一个链表连接起来,在处理的时候遍历列表, 然后对控制块进行操作,具体见 代码清单14_2。

代码清单 14‑2UDP控制块

#define IP_PCB \ /* 本地ip地址与远端IP地址 */ \ ip_addr_t local_ip; \ ip_addr_t remote_ip; \ /* 网卡id */ \ u8_t netif_idx; \ /* Socket 选项 */ \ u8_t so_options; \ /* 服务类型 */ \ u8_t tos; \ /* 生存时间 */ \ u8_t ttl \ IP_PCB_NETIFHINT /** UDP控制块 */ struct udp_pcb { IP_PCB; //指向下一个控制块 struct udp_pcb *next; //控制块状态 u8_t flags; /** 本地端口号与远端端口号 */ u16_t local_port, remote_port; /** 接收回调函数 */ udp_recv_fn recv; /** 回调函数参数 */ void *recv_arg; };

UDP控制块会使用IP层的一个宏定义IP_PCB,里面包括IP层需要使用的信息,如本地IP地址与目标IP地址(或者称为远端IP地址),服务类型、网卡、生存时间等,此外UDP控制块还要本地端口号与目标(远端)端口号,这两个字段很重要,UDP协议就是根据这些端口号识别应用线程,当UDP收到一个报文的时候,会遍历链表上的所有控制块,根据报文的目标端口号找到与本地端口号相匹配的UDP控制块,然后递交数据到上层应用,而如果找不到对应的端口号,那么就会返回一个端口不可达ICMP差错控制报文。

除此之外LwIP会为我们注册一个接收数据回调函数,当然啦,如果我们使用RAW API编程,这个回调函数就需要我们自己实现,在LwIP接收到一个给本地的数据时候, 就会调用这个回调函数,而recv字段就是指向这个回调函数的,其函数原型具体见 代码清单14_3。

代码清单 14‑3 udp_recv_fn函数原型

typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);

一般来说,我们使用NETCONN API或者是Socket API编程,是不需要我们自己去注册回调函数recv_udp(),因为这个函数LwIP内核会自动给我们注册,具体见 代码清单14_4。

代码清单 14‑4注册接收回调函数

void udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) { LWIP_ASSERT_CORE_LOCKED(); /* 注册回调函数 */ pcb->recv = recv; pcb->recv_arg = recv_arg; } udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);

LwIP中定义了一个名字为udp_pcbs的UDP控制块链表,记录主机中所有的UDP控制块,每个UDP协议的应用线程都能受到内核的处理, UDP控制块链表将UDP控制块连接起来,在收到数据需要处理的时候,内核变量链表,查找UDP控制块的信息, 从而调用对应的回调函数,当然,我们不使用RAW API编程的时候,回调函数只有一个,UDP控制块链表示意图具体见 图14_3。

图 14‑3UDP控制块链表



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有