From 231ef90fc50684aa190285ed740b29a67bbf6b5b Mon Sep 17 00:00:00 2001 From: xueyunfei Date: Wed, 27 Apr 2022 17:25:11 +0800 Subject: [PATCH] udp example:Optimization udp example with recv_msg --- .../protocols/sockets/udp_server/README.md | 1 + .../sockets/udp_server/main/udp_server.c | 42 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/examples/protocols/sockets/udp_server/README.md b/examples/protocols/sockets/udp_server/README.md index 31935f28b5..c29ab3ed6b 100644 --- a/examples/protocols/sockets/udp_server/README.md +++ b/examples/protocols/sockets/udp_server/README.md @@ -12,6 +12,7 @@ In order to create UDP client that communicates with UDP server example, choose There are many host-side tools which can be used to interact with the UDP/TCP server/client. One command line tool is [netcat](http://netcat.sourceforge.net) which can send and receive many kinds of packets. Note: please replace `192.168.0.167 3333` with desired IPV4/IPV6 address (displayed in monitor console) and port number in the following commands. +If want to use this RECVINFO function, please enable LWIP_NETBUF_RECVINFO in menuconfig,this function can only resolve the destination address of IPV4. In addition to those tools, simple Python scripts can be found under sockets/scripts directory. Every script is designed to interact with one of the examples. diff --git a/examples/protocols/sockets/udp_server/main/udp_server.c b/examples/protocols/sockets/udp_server/main/udp_server.c index 26ec46bc5f..3db2a89a97 100644 --- a/examples/protocols/sockets/udp_server/main/udp_server.c +++ b/examples/protocols/sockets/udp_server/main/udp_server.c @@ -57,6 +57,11 @@ static void udp_server_task(void *pvParameters) } ESP_LOGI(TAG, "Socket created"); +#if defined(CONFIG_LWIP_NETBUF_RECVINFO) && !defined(CONFIG_EXAMPLE_IPV6) + int enable = 1; + lwip_setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &enable, sizeof(enable)); +#endif + #if defined(CONFIG_EXAMPLE_IPV4) && defined(CONFIG_EXAMPLE_IPV6) if (addr_family == AF_INET6) { // Note that by default IPV6 binds to both protocols, it is must be disabled @@ -73,13 +78,33 @@ static void udp_server_task(void *pvParameters) } ESP_LOGI(TAG, "Socket bound, port %d", PORT); + struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6 + socklen_t socklen = sizeof(source_addr); + +#if defined(CONFIG_LWIP_NETBUF_RECVINFO) && !defined(CONFIG_EXAMPLE_IPV6) + struct iovec iov; + struct msghdr msg; + struct cmsghdr *cmsgtmp; + u8_t cmsg_buf[CMSG_SPACE(sizeof(struct in_pktinfo))]; + + iov.iov_base = rx_buffer; + iov.iov_len = sizeof(rx_buffer); + msg.msg_control = cmsg_buf; + msg.msg_controllen = sizeof(cmsg_buf); + msg.msg_flags = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_name = (struct sockaddr *)&source_addr; + msg.msg_namelen = socklen; +#endif + while (1) { - ESP_LOGI(TAG, "Waiting for data"); - struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6 - socklen_t socklen = sizeof(source_addr); +#if defined(CONFIG_LWIP_NETBUF_RECVINFO) && !defined(CONFIG_EXAMPLE_IPV6) + int len = recvmsg(sock, &msg, 0); +#else int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen); - +#endif // Error occurred during receiving if (len < 0) { ESP_LOGE(TAG, "recvfrom failed: errno %d", errno); @@ -90,6 +115,15 @@ static void udp_server_task(void *pvParameters) // Get the sender's ip address as string if (source_addr.ss_family == PF_INET) { inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1); +#if defined(CONFIG_LWIP_NETBUF_RECVINFO) && !defined(CONFIG_EXAMPLE_IPV6) + for ( cmsgtmp = CMSG_FIRSTHDR(&msg); cmsgtmp != NULL; cmsgtmp = CMSG_NXTHDR(&msg, cmsgtmp) ) { + if ( cmsgtmp->cmsg_level == IPPROTO_IP && cmsgtmp->cmsg_type == IP_PKTINFO ) { + struct in_pktinfo *pktinfo; + pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgtmp); + ESP_LOGI(TAG, "dest ip: %s\n", inet_ntoa(pktinfo->ipi_addr)); + } + } +#endif } else if (source_addr.ss_family == PF_INET6) { inet6_ntoa_r(((struct sockaddr_in6 *)&source_addr)->sin6_addr, addr_str, sizeof(addr_str) - 1); }