I have an issue where my code connects a TCP socket to a web server then fetches some data with recv, but it eventually fails returning errno 104 (ECONNRESET) once it has read 4320 bytes.
The application is for connecting to a UPnP IGD and attempting to add a port mapping and mostly works up until it needs to read a file from the IGD that happens to be bigger than 4320 bytes. The code is fairly portable and I can compile the application on Linux and it runs fine, including fetching files bigger than 4320 bytes.
4320 happens to be 3 times the default maximum segment size (MSS) of 1440, so I'm hoping this is just a configuration issue that can be fixed by changing some settings. I tried enabling some LWiP debug output but it made matters worse and caused ECONNRESET errors on files smaller than 4320 bytes.
Before the app receives the ECONNRESET, the debug output shows
then a short while latertcp_slowtmr: no active pcbs
thenlwip_recv_tcp: netconn_recv err=-7, pbuf=0x0
and finallylwip_recv_tcp: netconn_recv err=-14, pbuf=0x1
.lwip_recv_tcp: p == NULL, error is "Connection reset."!
I dug through the code and found that
is related to LWIP_MAX_LISTENING_TCP which I increased from 16 to 32 but it had no effect.no active pcbs
The function that fetches files from the IGD (which works on Linux) is as follows:
- struct http_req {
- int port, path_offset, len;
- char host[16], buf[1];
- };
- void http_req_run(struct http_req *q, char *body, int blen, http_req_f *heard, void *ctx)
- {
- if (!q)
- return;
- struct sockaddr_in sa = {0};
- sa.sin_family = AF_INET;
- sa.sin_port = htons(q->port);
- inet_aton(q->host, &sa.sin_addr);
- ESP_LOGD("UPNP", "TX %s%s", q->buf, body ? body : "");
- int s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP), got = 0, total = 0;
- if (s < 0)
- ESP_LOGE("UPNP", "socket error %i", errno);
- else if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) < 0)
- ESP_LOGE("UPNP", "connect error %i", errno);
- else if (send(s, q->buf, q->len, 0) < 0)
- ESP_LOGE("UPNP", "send header error %i", errno);
- else if (send(s, "\r\n", 2, 0) < 0)
- ESP_LOGE("UPNP", "send CRLF error %i", errno);
- else if (body && send(s, body, blen, 0) < 0)
- ESP_LOGE("UPNP", "send body error %i", errno);
- else while ((got = recv(s, q->buf, q->len, 0)) > 0) {
- q->buf[got] = 0; ESP_LOGD("UPNP", "RX %i %s", got, q->buf);
- heard(ctx, q->buf, got);
- total += got;
- }
- if (got < 0)
- ESP_LOGE("UPNP", "http_req_run recv %i, read %i bytes", errno, total);
- close(s);
- }
Cheers
Paul