Problem when uisng read function to get data from socket

Zingemneire
Posts: 68
Joined: Tue Apr 17, 2018 7:35 am

Problem when uisng read function to get data from socket

Postby Zingemneire » Tue Sep 11, 2018 2:21 pm

Hi all,

I am back with one more question:

I am trying to use this bit of code which is part of the HTTP_request_example_main.c code:

Code: Select all

       struct timeval receiving_timeout;
        receiving_timeout.tv_sec = 5;
        receiving_timeout.tv_usec = 0;
        if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &receiving_timeout,
                sizeof(receiving_timeout)) < 0) {
            ESP_LOGE(TAG, "... failed to set socket receiving timeout");
            close(s);
            vTaskDelay(4000 / portTICK_PERIOD_MS);
            continue;
        }
        ESP_LOGI(TAG, "... set socket receiving timeout success");

        /* Read HTTP response */
        do {
            bzero(recv_buf, sizeof(recv_buf));
            r = read(s, recv_buf, sizeof(recv_buf)-1);
            for(int i = 0; i < r; i++) {
                putchar(recv_buf[i]);
            }
        } while(r > 0);
I have gotten to the point where I do an HTTP Post operation to a bit of server software and see an answer being sent back. Using WireShark I can see the POST operation taking place and can also see the server send this reply back to the correct Ip address and port:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 276
ETag: W/"114-42fe4o8AhUSPVkQArHmDfvsQ0j4"
Date: Tue, 11 Sep 2018 14:00:45 GMT
Connection: keep-alive

JSON data....


For clarity I have omitted the printable text formatted IP and TCP headers and the actual JSON text data as it minified and therefore not easily readable. What is sure though is that all the headers and the JSON text are 100% OK.

What happens is that if I call the read function it will time out after 5 seconds, as set in the options, but it returns error -1 and sets the "errno" value to 11 ( EAGAIN ). I get none of the data that I know is sent back by the server via WireShark?

BTW: i have used ARC as a client application from another computer and there it works. The answer I see being sent by the server to the client using WireShark is properly received.

Is there anyone with an idea as to why the ESP32 software example would do that?

Still no solution found but a slight correction: once in a blue moon it does read the answer sent back from the server but usually it does not.

Zingemneire
Posts: 68
Joined: Tue Apr 17, 2018 7:35 am

Re: Problem when uisng read function to get data from socket

Postby Zingemneire » Thu Sep 13, 2018 9:37 am

Hi,

It took me a long time to solve this one but in the end I found the reason and how to solve it.

First of all I replaced the "read" function with the "recv" function with a MSG_DONTWAIT flag and handled the timeout myself instead of letting the "read" function do that.
That allowed me to see what happens over time and see exactly what the "recv" function returns when you use it to try and read from a socket.
  • At first it returns "-1" with errno EAGAIN which is logical as the reply has not come in yet.
  • Then it returns a certain amount of received bytes, typically the total amount of bytes in the message but not necessarily.
  • If the amount of bytes was the same as the amount of bytes in the message the next call to "recv" returns returns "-1" with errno EAGAIN.
The last call result could also occur in case some bytes still need to come in so that is why the "read" function continues to call "recv" function until the specified timeout expires. At the end of that timeout the returned result is always "-1" and EAGAIN because the message has long since been sent and received.

The solution is relatively simple: during the timeout period call "recv" regularly, count the total amount of received bytes, check it against the required length of the HTTP reply you expect and break out of the timeout loop if there is a match.

Conclusion: it did work but appeared not to as the whole thing was followed by a check on the returned "-1" value ( error ) from the "read" which triggered the assumption that nothing had been received.

Ah well: we live and learn.

Resch2061
Posts: 40
Joined: Mon May 01, 2017 1:56 pm

Re: Problem when uisng read function to get data from socket

Postby Resch2061 » Thu Sep 13, 2018 11:58 am

Thanks for posting your findings. I'm sure this'll be useful to a lot of people in the future. Can't tell you how many times I've ran into a problem, only to find 'I solved it' as the final post in the thread.

Image

Who is online

Users browsing this forum: Bing [Bot] and 69 guests