1# BearPi-HM_Nano开发板WiFi编程开发——UDP客户端 2本示例将演示如何在BearPi-HM_Nano开发板上使用socket编程创建UDP客户端,向服务端发送固定消息并接收服务端返回的消息。 3 4 5## socket API分析 6本案例主要使用了以下几个API完socket编程实验。 7### socket() 8 9```c 10sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) //AF_INT:ipv4, SOCK_DGRAM:udp协议 11``` 12**描述:** 13 14在网络编程中所需要进行的第一件事情就是创建一个socket,无论是客户端还是服务器端,都需要创建一个socket,该函数返回socket文件描述符,类似于文件描述符。socket是一个结构体,被创建在内核中。 15### sendto() 16```c 17int sendto(socket s, const void *msg, int len, unsigned int flags, const struct sockaddr *to , int token); 18``` 19**描述:** 20 21sendto() 用来将数据由指定的socket传给对方主机。参数s为已建立连接的socket。参数msg指向待发送的数据,参数flags 一般设0。 22 23### recvfrom() 24```c 25int recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen); 26``` 27**描述:** 28从指定地址接收UDP数据包。 29 30 31**参数:** 32 33|参数名|描述| 34|:--|:------| 35| s | socket描述符。 | 36| buf | 消息接收后的缓冲区。 | 37| len | 缓冲区的容量。 | 38| flags | 该参数一般为0。 | 39| from | 指向发送数据的对端地址信息的结构体,如果为NULL,不储存对端地址。 | 40| fromlen | 指向from结构体长度值,如果from为NULL,该值也应为NULL。 | 41 42 43 44## 软件设计 45 46**主要代码分析** 47 48完成UDP的通信过程需要以下几步。 49 501. 通过 `socket` 接口创建一个socket,`AF_INT`表示ipv4,`SOCK_DGRAM`表示使用dup协议。 512. 调用 `sendto` 接口发送数据到服务端。 523. 调用 `recvfrom` 接口接收服务端发来的数据。 53 54 55```c 56static void UDPClientTask(void) 57{ 58 //在sock_fd 进行监听,在 new_fd 接收新的链接 59 int sock_fd; 60 61 //服务器的地址信息 62 struct sockaddr_in send_addr; 63 socklen_t addr_length = sizeof(send_addr); 64 char recvBuf[512]; 65 66 //连接Wifi 67 WifiConnect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD); 68 69 //创建socket 70 if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 71 perror("create socket failed!\r\n"); 72 exit(1); 73 } 74 75 //初始化预连接的服务端地址 76 send_addr.sin_family = AF_INET; 77 send_addr.sin_port = htons(CONFIG_SERVER_PORT); 78 send_addr.sin_addr.s_addr = inet_addr(CONFIG_SERVER_IP); 79 addr_length = sizeof(send_addr); 80 81 //总计发送 count 次数据 82 while (1) { 83 bzero(recvBuf, sizeof(recvBuf)); 84 85 //发送数据到服务远端 86 sendto(sock_fd, send_data, strlen(send_data), 0, (struct sockaddr *)&send_addr, addr_length); 87 88 //线程休眠一段时间 89 sleep(TASK_DELAY_10S); 90 91 //接收服务端返回的字符串 92 recvfrom(sock_fd, recvBuf, sizeof(recvBuf), 0, (struct sockaddr *)&send_addr, &addr_length); 93 printf("%s:%d=>%s\n", inet_ntoa(send_addr.sin_addr), ntohs(send_addr.sin_port), recvBuf); 94 } 95 96 //关闭这个 socket 97 closesocket(sock_fd); 98} 99``` 100 101## 编译调试 102 103### 修改 BUILD.gn 文件 104 105修改 `device\board\bearpi\bearpi_hm_nano\app` 路径下 BUILD.gn 文件,指定 `udp_client` 参与编译。 106```r 107#"D1_iot_wifi_sta:wifi_sta", 108#"D2_iot_wifi_sta_connect:wifi_sta_connect", 109"D3_iot_udp_client:udp_client", 110#"D4_iot_tcp_server:tcp_server", 111#"D5_iot_mqtt:iot_mqtt", 112#"D6_iot_cloud_oc:oc_mqtt", 113``` 114 115 116### 运行结果<a name="section18115713118"></a> 117 118使用 Socket tool 创建UDP服务端用于测试,如下图所示。 119 120 121 122示例代码编译烧录后,按下开发板的RESET按键,在socket tool的数据发送窗口输入要发送的数据,点击发送后开发板会回复固定消息,如下图所示,且开发板收到消息后会通过日志打印出来。 123 124``` 125192.168.0.175:8888=>Hello! BearPi-HM_nano UDP Client! 126``` 127 128 129