很多l(xiāng)wip的教程里都有udp的回環(huán)程序例子,就是每收到一包數(shù)據(jù)立刻回環(huán)發(fā)出去。如下:
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數(shù)據(jù)。UDP協(xié)議一幀(帶幀頭)最長(zhǎng)可以發(fā)送64KB的數(shù)據(jù),在實(shí)際使用中如果想接收一整幀在處理,可以使用類似如下的程序:
struct?udp_par_struct
{
? u8 receive_state; ? ? ? ? ? ? ??//接收狀態(tài)
? u32 from_addr; ? ? ? ? ? ? ? ? ?//IP地址——來(lái)源
? u16 from_port; ? ? ? ? ? ? ? ? ?//端口——來(lái)源
??uint32_t?udp_re_num; ? ? ? ? ? ?//接收數(shù)據(jù)長(zhǎng)度
??uint32_t?udp_tx_num; ? ? ? ? ? ?//發(fā)送數(shù)據(jù)長(zhǎng)度
??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);?//先復(fù)制第一個(gè)內(nèi)存塊的包
? 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");
}
以上代碼中使用結(jié)構(gòu)體udp_par_struct(例子最大接收2000字節(jié),可自己調(diào)整)存儲(chǔ)UDP的數(shù)據(jù)和狀態(tài),通過(guò)判斷p->next是否為空指針來(lái)判斷這整幀是否接收完畢。接收完整幀后通過(guò)結(jié)構(gòu)體中的receive_state 置標(biāo)志位。同時(shí)可存儲(chǔ)其他參數(shù)。
這樣可接收一整幀之后再進(jìn)行協(xié)議處理。
閱讀全文