Working UDP client on any version of IDF?
Working UDP client on any version of IDF?
Does any one have a working udp client example? The udp_client example in the examples/protocols/socket/udp_client doesn't seem to work. I've used Wireshark to try to capure the message sent but it doesn't send. The udp_server example works but I want an example that doesn't rely on getting its destination from the packet it receives. I just want to be able to setup a client with a destination ipv4 address, port and send packets. I suspect that there is a arp problem which would explain why the client doesn't send the packet. Maybe I'm the only one with this problem?
I've even tried compiling Linux udp client examples as well but they don't seem to work either. I'm using a ESP32-lyraT v4.3 board and esp idf v3.2.2. I plan on using the esp32 as a WiFi access point and it seems work with the udp_server code. I never thought that UDP would be this difficult to implement on the ESP32 compared to the ESP8266. The only reason I switched from the esp8266 to the esp32-lyrat board was because of its audio streaming capabilities that I will latter use to stream audio over UDP. Not being able to send UDP packets is no go for me. My development environment is run under Linux Mint 19.2. Anyone having any luck with UDP sendto
I've even tried compiling Linux udp client examples as well but they don't seem to work either. I'm using a ESP32-lyraT v4.3 board and esp idf v3.2.2. I plan on using the esp32 as a WiFi access point and it seems work with the udp_server code. I never thought that UDP would be this difficult to implement on the ESP32 compared to the ESP8266. The only reason I switched from the esp8266 to the esp32-lyrat board was because of its audio streaming capabilities that I will latter use to stream audio over UDP. Not being able to send UDP packets is no go for me. My development environment is run under Linux Mint 19.2. Anyone having any luck with UDP sendto
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Working UDP client on any version of IDF?
As far as I know, the UDP examples should work - I think we even have testcases for those that get run whenever an esp-idf version gets released. What is your setup exactly?
Re: Working UDP client on any version of IDF?
I tried to build a project from examples (UDP Client).
It didn't work for me either. I changed the code a little (removed the standard checks).
I keep getting messages:
And so endlessly and quickly.
The vTaskDelay (2000 / portTICK_PERIOD_MS) doesn't even fire.
My code:
Any idea why it doesn't work?
It didn't work for me either. I changed the code a little (removed the standard checks).
I keep getting messages:
Code: Select all
UDP: Socket created, sending to 192.168.1.108:1900
UDP: Error occurred during sending: errno 118
UDP Socket Restarting
...
The vTaskDelay (2000 / portTICK_PERIOD_MS) doesn't even fire.
My code:
Code: Select all
#define HOST_IP_ADDR "255.255.255.255"
#define PORT 1900
static const char * TAG = "UDP";
static const char * payload = "Message from ESP32 ";
static void taskUDPClient(void * pvParameters) {
char rx_buffer[128];
int addr_family = 0;
int ip_protocol = 0;
while (1) {
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
int sock = socket(addr_family, SOCK_DGRAM, ip_protocol);
if (sock < 0) {
send_uart("UDP", "Unable to create socket", NULL);
break;
}
//send_uart("UDP", "Socket created, sending", NULL);
ESP_LOGI(TAG, "Socket created, sending to %s:%d", HOST_IP_ADDR, PORT);
while (1) {
int err = sendto(sock, payload, strlen(payload), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (err < 0) {
ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);[Codebox=c file=Untitled.c][/Codebox]
break;
}
send_uart("UDP", "Message sent", NULL);
struct sockaddr_in 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 (len < 0) {
/* Ошибка при получении */
ESP_LOGE(TAG, "recvfrom failed: errno %d", errno);
break;
} else {
/* Данные получены */
rx_buffer[len] = '\0';
send_uart("UDP", "Received Data", rx_buffer);
if (strncmp(rx_buffer, "OK: ", 4) == 0) {
send_uart("UDP", "Received expected message, reconnecting", NULL);
break;
}
}
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
if (sock != -1) {
send_uart("UDP", "Socket Restarting", NULL);
shutdown(sock, 0);
close(sock);
}
}
vTaskDelete(NULL);
}
// Инициализация UDP Server
esp_err_t udpClientInit() {
if (xTaskCreate(taskUDPClient, "taskUDPClient", 4096, NULL, 5, NULL) != pdPASS) {
return ESP_FAIL;
}
return ESP_OK;
}
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Working UDP client on any version of IDF?
Are you sure WiFi is actually connected and your ESP32 has an IP before you start sending?
Re: Working UDP client on any version of IDF?
Yes, 100%.
I also get the time from the server, and it is correct. The application works stably, nothing crashes.
I also started UDP Server and it works fine, returns packets stably.
The only thing is UDP Client.
I also get the time from the server, and it is correct. The application works stably, nothing crashes.
I also started UDP Server and it works fine, returns packets stably.
The only thing is UDP Client.
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Working UDP client on any version of IDF?
No idea what it might be. For shits and giggles, I copy-pasted your code into the udp_client app (from current esp-idf master) and I have absolutely no issues getting the packets sent. To be fair, your ESP-IDF version is quite old (and actually out of support by now) , so it may be that there's some differences there.Whoops, post I replied to is not OP.
Re: Working UDP client on any version of IDF?
How should reception work if many devices answer?
After all, I'm sending a request, I pass through the reception 1 time (96 lines) and the delay ...
And if many devices respond, how do you handle them?
Is the delay in the right place set?
I should have many answers.
After all, I'm sending a request, I pass through the reception 1 time (96 lines) and the delay ...
And if many devices respond, how do you handle them?
Is the delay in the right place set?
I should have many answers.
Re: Working UDP client on any version of IDF?
I need to send requests to the broadcast address not constantly, but once every 5 seconds and then wait 30 seconds. This part works provided that there is a device on the network that responds to requests.
The essence of the work is as follows:
I wrapped the data receiving block in a loop while (1)
I create a task taskListenExit to change the flag receiverLoopFlag (in order to exit the reception cycle)
I send a broadcast request and for 2 seconds I am in a receive cycle in order to receive responses from all devices
after 2 seconds I have to exit the receive loop and send the next request
The problem is, I cannot get out of the receive loop if there are no devices on the network (no response).
Tell me, am I doing something wrong?
Why am I not getting out of the loop
I change the flag and the condition becomes false
I checked in the function of task static void taskListenExit(), it is called correctly and changes the value of the flag.
The essence of the work is as follows:
I wrapped the data receiving block in a loop while (1)
I create a task taskListenExit to change the flag receiverLoopFlag (in order to exit the reception cycle)
I send a broadcast request and for 2 seconds I am in a receive cycle in order to receive responses from all devices
after 2 seconds I have to exit the receive loop and send the next request
The problem is, I cannot get out of the receive loop if there are no devices on the network (no response).
Tell me, am I doing something wrong?
Code: Select all
/* Receive data cycle status (for forced exit if no responses) */
bool receiverLoopFlag = 1;
/* The task of exiting the loop waiting for responses */
static void taskListenExit() {
while (1) {
vTaskDelay(SMALL_PERIOD_SCAN * 1000 / portTICK_PERIOD_MS);
receiverLoopFlag = 0;
}
}
static void taskUDPClient(void * pvParameters) {
char rx_buffer[1024];
int addr_family = 0;
int ip_protocol = 0;
while (1) {
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
int sock = socket(addr_family, SOCK_DGRAM, ip_protocol);
if (sock < 0) {
break;
}
int iRequest = NUM_REQUESTS;
/* Cycle of periodically sending a packet to search for devices */
while (1) {
int err = sendto(sock, SEARCH_PHRASE, strlen(SEARCH_PHRASE), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (err < 0) {
break;
}
receiverLoopFlag = 1;
/* Waiting cycle for responses */
while (receiverLoopFlag == 1) {
struct sockaddr_in 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 (len < 0) {
break;
}
if (len > 0) {
/* Package processing */
}
}
iRequest--;
if (iRequest > 0) {
vTaskDelay(SMALL_PERIOD_SCAN * 1000 / portTICK_PERIOD_MS);
} else {
vTaskDelay(LONG_PERIOD_SCAN * 1000 / portTICK_PERIOD_MS);
iRequest = NUM_REQUESTS;
}
}
if (sock != -1) {
shutdown(sock, 0);
close(sock);
}
}
vTaskDelete(NULL);
}
}
// INIT UDP Client
esp_err_t udpClientInit() {
if (xTaskCreate(taskUDPClient, "taskUDPClient", 4096, NULL, 5, NULL) != pdPASS) {
return ESP_FAIL;
}
if (xTaskCreate(taskListenExit, "taskListenExit", 4096, NULL, 4, NULL) != pdPASS) {
return ESP_FAIL;
}
return ESP_OK;
}
Code: Select all
while (receiverLoopFlag == 1)
I checked in the function of task static void taskListenExit(), it is called correctly and changes the value of the flag.
-
- Posts: 9709
- Joined: Thu Nov 26, 2015 4:08 am
Re: Working UDP client on any version of IDF?
You're not getting out of the loop because recvfrom() won't return until it received a packet. If it does not receive a packet, it will never return. One of the ways around this would be to e.g. use select() with a timeout to wait until either data becomes available on the socket or the timeout hits. This guarantees your program will continue whether or not it receives a response.
Re: Working UDP client on any version of IDF?
Thanks for the advice!
But I still haven't figured out how to work with select ()
I used advanced settings
It works, but I don't know if it is correct.
But I still haven't figured out how to work with select ()
I used advanced settings
Code: Select all
struct timeval read_timeout;
read_timeout.tv_sec = UDPC_RESPONSE_TIMEOUT;
//...
setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, & read_timeout, sizeof read_timeout);
Who is online
Users browsing this forum: Google [Bot] and 64 guests