前言
????????前面我們用W5500-EVB-PICO 開發板在TCP Client和TCP Server模式下,分別進行數據回環測試,本章我們將用開發板在UDP Server模式下進行數據回環測試。
UDP是什么?什么是UDP Server?能干什么?
????????UDP (User Dataqram Protocol) 是一種無連接的、不可靠的傳輸協議,用于在計算機網絡上傳輸數據UDP Server是指UDP網絡服務的服務器端連接,用于接收客戶端的數據報文并返回響應,實現網絡數據的交互。
????????UDP Server的主要作用是接收客戶端發送的數據報文,并進行處理和響應。通過UDP Server,客戶端可以將數據報文發送到服務器,并從服務器接收響應。由于UDP是無連接的,因此每個數據報文都是獨立處理的,服務器對于未收到的數據報文不會重傳。
????????在UDP Server中,服務器程序需要指定監聽的端口號,并使用UDP協議接收客戶端發送的數據報文。一旦接收到數據報文,服務器程序會對報文進行處理,并返回相應的響應報文。
????????因此,UDP Server可以幫助設備實現數據報文的快速傳輸和響應,適用于一些對于數據傳輸速度和實時性要求較高的應用,如視頻直播、語音通話等。在UDP Server中,由于數據報文的傳輸是不可靠的,因此需要客戶端程序進行重傳和超時處理,以保證數據的可靠傳輸。
UDP Server 和 UDP Client有何不同?
UDP服務器:
- 首先初始化
- 打開特定端口監聽
- 可以接受多個客戶端連接
UDP客戶端:
- 指定目標IP和端口
- 發送數據
從套接字編程角度來看,兩者完全相同。因此我們僅用UDP Server來做數據回環測試。
連接方式
使開發板和我們的電腦處于同一網段:
- 開發板通過交叉線直連主機
- 開發板和主機都接在路由器LAN口
測試工具
- 網路調試工具(任意)
- wireshark抓包工具
回環測試
1.相關代碼
我們打開例程中庫文件的loopback.c文件,可以看到udp server回環測試函數,它有三個參數:socket(套接字)端口號(0~7個端口,可開8路socket)、數據收發緩存buf、監聽端口;原理上依舊是通過Switch狀態機輪詢socket端口(所開端口的套接字)狀態,根據不同狀態做出相應處理,與tcp不同的是,udp只有做了兩個狀態處理,如果為關閉狀態就初始化socket狀態為udp協議模式,并開始監聽設置的端口;如果狀態已經處于udp模式,即socket初始化后,就進行判斷是否收到數據,收到就進行回傳。如下所示:
int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port)
{int32_t ret;uint16_t size, sentsize;uint8_t destip[4];uint16_t destport;switch(getSn_SR(sn)){case SOCK_UDP :if((size = getSn_RX_RSR(sn)) > 0){if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;ret = recvfrom(sn, buf, size, destip, (uint16_t*)&destport);buf[ret]=0x00;printf("recv form[%d.%d.%d.%d][%d]: %s\n", destip[0],destip[1],destip[2],destip[3],destport,buf);if(ret <= 0){
#ifdef _LOOPBACK_DEBUG_printf("%d: recvfrom error. %ld\r\n",sn,ret);
#endifreturn ret;}size = (uint16_t) ret;sentsize = 0;while(sentsize != size){ret = sendto(sn, buf+sentsize, size-sentsize, destip, destport);if(ret < 0){
#ifdef _LOOPBACK_DEBUG_printf("%d: sendto error. %ld\r\n",sn,ret);
#endifreturn ret;}sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.}}break;case SOCK_CLOSED:
#ifdef _LOOPBACK_DEBUG_//printf("%d:UDP loopback start\r\n",sn);
#endifif((ret = socket(sn, Sn_MR_UDP, port, 0x00)) != sn)return ret;
#ifdef _LOOPBACK_DEBUG_printf("%d:Opened, UDP loopback, port [%d]\r\n", sn, port);
#endifbreak;default :break;}return 1;
}
然后我們在主函數里循環調用測試函數即可。可以看到里面還注釋了一個udp client回環測試函數,這個基本跟udp server相同,獨立出來是為了方便用戶自己進行測試,這里不在演示。如下所示:
#define SOCKET_ID 0
#define ETHERNET_BUF_MAX_SIZE (1024 * 2)void network_init(void);wiz_NetInfo net_info = {.mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e},.ip = {192, 168, 1, 10},.sn = {255, 255, 255, 0},.gw = {192, 168, 1, 1},.dns = {8, 8, 8, 8},.dhcp = NETINFO_STATIC};
wiz_NetInfo get_info;
static uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0,};
static uint8_t destip[4]={192, 168, 1, 2};
static uint16_t destport = 8080;
static uint16_t local_port =8000;
int main()
{ stdio_init_all();sleep_ms(2000);network_init();while(true){// loopback_udpc(SOCKET_ID, ethernet_buf, destip, destport);loopback_udps(SOCKET_ID, ethernet_buf, local_port);sleep_ms(500);}}void network_init(void)
{uint8_t temp;wizchip_initialize();printf("W5500 udp test example.\r\n");sleep_ms(2000);wizchip_setnetinfo(&net_info);print_network_information(get_info);sleep_ms(2000);
}
2.測試現象
編譯燒錄后,打開串行監視器,看到網絡信息配置成功后,打開兩個網絡調試助手,參數依次設置為UDP、本機的IP、8080,注意另一個調試助手的端口參數設置跟第一個不可以相同,避免沖突;這里將其設置為8081,完成后打開;然后遠程IP和端口選擇我們開發板設置的IP和端口,我這里是192.168.1.10 : 8000,然后我們讓第一個調試助手發送0~9十個阿拉伯數字,第二個發送字符串:hello wiznet,可以看到串口打印收到不同客戶端的數據,而且調試助手也分別收到了相對應的數據回傳。如下圖所示:
?我們可以打開wireshark抓包工具,輸入命令<ip.addr == 192.168.1.10 and udp>過濾數據包(IP地址改成自己電腦的IP或者開發板的IP地址即可);然后兩個調試助手依次發送,可以到抓到的數據包。如下圖所示:
相關鏈接?
本章相關例程鏈接https://gitee.com/wiznet-hk/w5500-evb-pico-routine.git