Page 247

The do loop at the end of maintask i.e.:

    char buffer[2048];
    do
    {
n = read(sockfd, buffer, 2048); buffer[n] = 0; printf("\ndata received %d\n\n", n); printf("%s\n", buffer); } while (n > 0);

Is too simple to put the data fragments back together correctly in the buffer.

The correct code is:

 char buffer[2048];
int m=0;
do
{
int n = read(sockfd, buffer+m, 2048-m);
if(n<=0)break;
buffer[n+m] = 0;
printf("\ndata received %d\n\n", n);
printf("%s\n", buffer+m);
m=m+n;
} while(true);
printf("Final buffer\n\n%s\n", buffer);

Notice that we now wait for the HTTP server to timeout and disconnect from the socket connection – this can take tens of seconds.

Of course, we can do much better than this simple example. For one thing each socket operation needs to be checked for errors.

Page 250

A better way to set the number of sockets in select is to use sockfd+1.

Change:

n = select(5, &rfds, NULL, NULL, &tv);

To

n = select(sockfd+1, &rfds, NULL, NULL, &tv);

 

Page 251

The program as given doesn't load fragments of received data into the buffer correctly. Replace the code by: 

    char buffer[2048];
    int m = 0;
n = 0;
fd_set rfds; struct timeval tv; do { FD_ZERO(&rfds); FD_SET(sockfd, &rfds); tv.tv_sec = 6; tv.tv_usec = 0; n = select(sockfd + 1, &rfds, NULL, NULL, &tv); if (n < 0) { printf("read error %X\n", errno); break; }
if (n == 0) { printf("read timeout\n"); break; }
n = read(sockfd, buffer + m, 2048 - m); if (n > 0) { buffer[n + m] = 0; printf("\ndata received %d\n\n", n); printf("%s\n", buffer + m); m = m + n; } if (n < 0){ printf("read error %X\n", errno); break; } printf("\ndata received on socket %d %d\n\n", sockfd, n); } while (true); printf("Final buffer\n\n%s\n", buffer); printf("close socket %d\n", sockfd); close(sockfd); vTaskDelete(NULL); }