mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
udp example:Optimization udp example with recv_msg
This commit is contained in:
parent
9b64c40981
commit
231ef90fc5
@ -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.
|
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.
|
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.
|
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.
|
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.
|
||||||
|
|
||||||
|
@ -57,6 +57,11 @@ static void udp_server_task(void *pvParameters)
|
|||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "Socket created");
|
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 defined(CONFIG_EXAMPLE_IPV4) && defined(CONFIG_EXAMPLE_IPV6)
|
||||||
if (addr_family == AF_INET6) {
|
if (addr_family == AF_INET6) {
|
||||||
// Note that by default IPV6 binds to both protocols, it is must be disabled
|
// 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);
|
ESP_LOGI(TAG, "Socket bound, port %d", PORT);
|
||||||
|
|
||||||
while (1) {
|
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Waiting for data");
|
|
||||||
struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
|
struct sockaddr_storage source_addr; // Large enough for both IPv4 or IPv6
|
||||||
socklen_t socklen = sizeof(source_addr);
|
socklen_t socklen = sizeof(source_addr);
|
||||||
int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen);
|
|
||||||
|
|
||||||
|
#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");
|
||||||
|
#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
|
// Error occurred during receiving
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
ESP_LOGE(TAG, "recvfrom failed: errno %d", errno);
|
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
|
// Get the sender's ip address as string
|
||||||
if (source_addr.ss_family == PF_INET) {
|
if (source_addr.ss_family == PF_INET) {
|
||||||
inet_ntoa_r(((struct sockaddr_in *)&source_addr)->sin_addr, addr_str, sizeof(addr_str) - 1);
|
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) {
|
} else if (source_addr.ss_family == PF_INET6) {
|
||||||
inet6_ntoa_r(((struct sockaddr_in6 *)&source_addr)->sin6_addr, addr_str, sizeof(addr_str) - 1);
|
inet6_ntoa_r(((struct sockaddr_in6 *)&source_addr)->sin6_addr, addr_str, sizeof(addr_str) - 1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user