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