很多lwip的教程里都有udp的回环程序例子,就是每收到一包数据立刻回环发出去。如下:
void udp_echo_XXX_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port){/* Connect to the remote client */udp_connect(upcb, addr, UDP_CLIENT_PORT);/* Tell the client that we have accepted it */udp_send(upcb, p);/* free the UDP connection, so we can accept new clients */udp_disconnect(upcb);/* Free the p buffer */pbuf_free(p);}
这段代码中p是一段udp数据。UDP协议一帧(带帧头)最长可以发送64KB的数据,在实际使用中如果想接收一整帧在处理,可以使用类似如下的程序:
struct udp_par_struct{u8 receive_state; //接收状态u32 from_addr; //IP地址——来源u16 from_port; //端口——来源uint32_t udp_re_num; //接收数据长度uint32_t udp_tx_num; //发送数据长度uint8_t udp_send_date[2000];uint8_t udp_receive_date[2000];};void udp_recv_demo_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port){int receive_count = 0;unsigned char *receive_data;struct pbuf* P_next;struct udp_par_struct *udp_par_struct_date = (struct udp_par_struct*)arg;memcpy(udp_par_struct_date->udp_receive_date,p->payload,p->len); //先复制第一个内存块的包P_next = p->next;receive_count = receive_count + p->len;receive_data = &udp_par_struct_date->udp_receive_date[0] + p->len;while(P_next){if((receive_count + P_next->len) > sizeof(udp_par_struct_date->udp_receive_date)) break;memcpy(receive_data,P_next->payload,P_next->len);receive_data = receive_data + P_next->len;receive_count = receive_count + P_next->len;P_next = P_next->next;}pbuf_free(p);udp_par_struct_date->udp_re_num = receive_count;udp_par_struct_date->receive_state = UDP_RECEIVED;udp_par_struct_date->from_addr = addr->addr;udp_par_struct_date->from_port = port;xxx_print("receive IP = %d.%d.%d.%d ",udp_par_struct_date->from_addr&0xFF,(udp_par_struct_date->from_addr>>8)&0xFF,(udp_par_struct_date->from_addr>>16)&0xFF,(udp_par_struct_date->from_addr>>24)&0xFF);xxx_print("receive port = %d ",udp_par_struct_date->from_port);xxx_print("receive num = %d ",udp_par_struct_date->udp_re_num);for(int i = 0;i<receive_count;i++){xxx_print("0x%x ", udp_par_struct_date->udp_receive_date[i]);}xxx_print("nr");}
以上代码中使用结构体udp_par_struct(例子最大接收2000字节,可自己调整)存储UDP的数据和状态,通过判断p->next是否为空指针来判断这整帧是否接收完毕。接收完整帧后通过结构体中的receive_state 置标志位。同时可存储其他参数。
这样可接收一整帧之后再进行协议处理。
阅读全文
1952