accept function always returns EWOULDBLOCK

SteveD430
Posts: 2
Joined: Wed Nov 27, 2019 10:23 am

accept function always returns EWOULDBLOCK

Postby SteveD430 » Wed Nov 27, 2019 3:36 pm

Hi,

I am running the V4 Beta version of the Espressif IDF and am attempting to use an ESP32 as a socket server to send data to a C# dotnet client program. The socket server is operating in unblocked mode as there are a number of threads running (a separate thread is executing, receiving data from an external sensor). The thread that initiates the socket on the ESP32, binds, listens and then awaits on the accept is as follows:
  1. void SocketListenConnectTask (void *pvParamters)
  2. {
  3.     char addr_str[128];
  4.     int addr_family;
  5.     int ip_protocol;
  6.    
  7.     struct sockaddr_in dest_addr;
  8.    
  9.     dest_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  10.     dest_addr.sin_family = AF_INET;
  11.     dest_addr.sin_port = htons(PORT);
  12.     addr_family = AF_INET;
  13.     ip_protocol = IPPROTO_TCP;
  14.     inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str)-1);
  15.    
  16.     int listen_socket = socket(addr_family, SOCK_STREAM, ip_protocol);
  17.     if (listen_socket < 0)
  18.     {
  19.         ESP_LOGE(TAG, "Unable to create socket: Error No: %d", errno);
  20.         vTaskDelete(NULL);
  21.     }
  22.    
  23.     // Mark socket as non blocking.
  24.     int status = fcntl(listen_socket, F_SETFL, fcntl(listen_socket, F_GETFL, 0) | O_NONBLOCK);
  25.     if (status == -1)
  26.     {
  27.         ESP_LOGE(TAG, "Error setting non-blocking status: %s", strerror(errno));
  28.         vTaskDelete(NULL);
  29.     }
  30.    
  31.     int err = bind(listen_socket, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
  32.     if (err != 0)
  33.     {
  34.         ESP_LOGE(TAG, "Socket unable to bind: Error No: %s", strerror(errno));
  35.         close(listen_socket);
  36.         vTaskDelete(NULL);
  37.     }
  38.     err = listen(listen_socket, 1);
  39.     if (err != 0)
  40.     {
  41.         ESP_LOGE(TAG, "Socket unable to listen: Error No: %s", strerror(errno));
  42.         close(listen_socket);
  43.         vTaskDelete(NULL);
  44.     }
  45.     else
  46.     {
  47.     while (1)
  48.     {
  49.         bool client_connected = false;
  50.        
  51.         // Listening for Client connection.
  52.         while (!client_connected)
  53.         {
  54.             struct sockaddr source_addr;
  55.             uint addr_len = sizeof(source_addr);
  56.             telnet_socket = accept(listen_socket, (struct sockaddr *)&source_addr, &addr_len);
  57.             if (errno == EWOULDBLOCK)
  58.             {
  59.                 ESP_LOGI(TAG, "Awaiting connection");
  60.                 vTaskDelay(100);
  61.             }
  62.             else if (telnet_socket < 0)
  63.             {
  64.                 ESP_LOGE(TAG, "Unable to accept connection %s", strerror(errno));
  65.                 vTaskDelay(100); //vTaskDelete(NULL);
  66.             }
  67.             else
  68.             {
  69.                 ESP_LOGI(TAG, "Connected");
  70.                 client_connected = true;
  71.             }
  72.         }
  73.         telnetClientConnected = true;
  74.     }
  75.     }
  76. }
with, at the moment a small POC C# client code:
  1.    class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             Byte[] bytesReceived = new Byte[256];
  6.  
  7.             IPAddress iPAddress = IPAddress.Parse(args[0]);
  8.             IPEndPoint ipEndPoint = new IPEndPoint(iPAddress, 23);
  9.             Socket tempSocket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  10.             tempSocket.Connect(ipEndPoint);
  11.             if (tempSocket.Connected)
  12.             {
  13.                 int bytes = 0;
  14.                 do
  15.                 {
  16.                     bytes = tempSocket.Receive(bytesReceived, bytesReceived.Length, 0);
  17.                 } while (bytes > 0);
  18.             }
  19.  
  20.         }
  21.     }
The output from the ESP32 monitor provides me with the IP Address of the ESP32, and when I receive the first "Awaiting connection" message from the ESP I trigger the C# program in debug.

The C# program appears to connect successfully (tempSocket.Connected is true and the tempSocket object does have the correct IP Address and Port values), but, even though the C# client believes it is connected, I continue to get the "Awaiting Connection" mesage from the ESP32, indicating that the accept function is still returning errno == EWOULDBLOCK.

Any help or insight would be gratefully received.

Thanks

ESP_Sprite
Posts: 9770
Joined: Thu Nov 26, 2015 4:08 am

Re: accept function always returns EWOULDBLOCK

Postby ESP_Sprite » Thu Nov 28, 2019 4:31 am

From the manpage of accept:
On success, these system calls return a nonnegative integer that is a file descriptor for the accepted socket. On error, -1 is returned, and errno is set appropriately.
Note that it does *not* say that errno is set on success. In other words: you call can succeed but errno will still have whatever previous failure value is there. The solution is simple:

Code: Select all

if (telnet_socket == -1 && errno == EWOULDBLOCK)

SteveD430
Posts: 2
Joined: Wed Nov 27, 2019 10:23 am

Re: accept function always returns EWOULDBLOCK

Postby SteveD430 » Fri Nov 29, 2019 6:39 pm

Hi,

Thanks for the response. Your answer worked a treat. I must admit I was not expecting to receive both a positive connection response with an error no. So not only was the answer good, but also the insight into the comms libraries that they can operate in that manner is also appreciated.

Thanks

Steve D.

Who is online

Users browsing this forum: No registered users and 100 guests