LWIP Socket API: Accept the same client several times doesn't work

MajinFoo
Posts: 9
Joined: Sun Jan 21, 2018 9:06 pm

LWIP Socket API: Accept the same client several times doesn't work

Postby MajinFoo » Wed Apr 25, 2018 3:24 pm

Hello,

I have some problems with the LWIP Socket API for ESP32.

With the function accept() I am waiting for a tcp client to connect to the ESP32 as tcp server. Then I can receive data from the client via recv(). This works as expected.

Now I want to disconnect the client from the server and accept the socket from the same client again. To do this I close the socket and wait again for a client to connect to the server. This only works twice, the third call of accept() results in the return -1. revc() is now always unblocked, although no message is received.

Code: Select all

void tcp_test_task(void *par){
	char rec_buffer[128];
	char* rec_data;
	uint8_t rec_size;
	uint8_t client_disconnect = 1;
	int32_t res;
	const uint16_t server_port = 10;
	
	int32_t tcp_server_socket = 0;
	int32_t tcp_client_socket = 0;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t client_addr_len = sizeof(client_addr);

	tcp_server_socket = lwip_socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = lwip_htonl(INADDR_ANY);
	server_addr.sin_port = htons(server_port); 
	res = lwip_bind(tcp_server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
	
	res = lwip_listen(tcp_server_socket, 5);
	
	//Up to here there are no errors
	while(1){
		//Accept new client
		tcp_client_socket = lwip_accept(tcp_server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
		
		//After the third call of accept() it returns the error -1
		if (tcp_client_socket < 0){
			printf("Error in accept(): %d\n", tcp_client_socket);
		} 
		client_disconnect = 1;
		while(client_disconnect){
			//receive messages from the client
			rec_size = lwip_recv(tcp_client_socket, rec_buffer, 128, 0);
			if (rec_size == 0) { //client disconnected from server
				client_disconnect = 0; //go back to accept()
				lwip_close(tcp_client_socket);
			} else {
				rec_data = malloc((rec_size + 1) * sizeof(char));
				strncpy(rec_data, rec_buffer, rec_size);
				rec_data[rec_size] = '\0';
				if (!strcmp(rec_data, "Disconnect")){
					client_disconnect = 0; //go back to accept()
					lwip_close(tcp_client_socket);
				} 
				free(rec_data);
			}
		}
	}
}
I have no idea what i'm doing wrong. Why i can only accept two clients? Or is there another way to reconnect a client to a server?
Last edited by MajinFoo on Wed Apr 25, 2018 7:06 pm, edited 1 time in total.

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: LWIP Socket API: Accept the same client several times doesn't work

Postby kolban » Wed Apr 25, 2018 4:15 pm

When you get a -1 error code from accept(), the global variable errno will be set to give you additional information for the reason of the error. Can you log the value you get?
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: LWIP Socket API: Accept the same client several times doesn't work

Postby fly135 » Wed Apr 25, 2018 4:46 pm

I'm using the regular socket api... socket, listen, accept, and close. It works fine over and over.

Obviously if you get an error on the accept you should not go into the loop with the recv. You want to delay a bit and call accept again. Or if errno tells you something is wrong with the listening socket then you need to close it and reopen the whole listening process.

John A

MajinFoo
Posts: 9
Joined: Sun Jan 21, 2018 9:06 pm

Re: LWIP Socket API: Accept the same client several times doesn't work

Postby MajinFoo » Wed Apr 25, 2018 7:03 pm

@kolban: Thank you for this advice. With errno i get the following error:

Code: Select all

23 Too many open files in system
It looks like there are too many sockets open. Using make menuconfig I increased the maximum number of open sockets from 4 to 5. Now it was possible to accept one client more before the error occurred again. But that doesn't make sense to me, because I close every socket before accept().

I have read that closing a socket in LWIP can take a few minutes until the Socket is released again. But even after 10 minutes the error still occurred.

@fly135: If I close both sockets (server and client) after disconnecting from the client and reopen the whole listening process then accept() blocks forever. I also try the SO_REUSEADDR and SO_REUSEPORT option.

Code: Select all

setsockopt(tcp_server_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &(int){ 1 }, sizeof(int)) 

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: LWIP Socket API: Accept the same client several times doesn't work

Postby kolban » Wed Apr 25, 2018 8:07 pm

This might be a good time to break into studying WireShark. Where are you making your client calls from? By using WireShark we can likely verify that the connection between the client and the ESP32 has been closed correctly.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32


MajinFoo
Posts: 9
Joined: Sun Jan 21, 2018 9:06 pm

Re: LWIP Socket API: Accept the same client several times doesn't work

Postby MajinFoo » Thu Apr 26, 2018 12:26 pm

That's it! Using lwip_close() instead close() does not close the socket. Thank you so much!

There is another function lwip_close_r(). This function also closed the socket correctly. I wonder what is the difference between close(), lwip_close_r() and lwip_close().

Who is online

Users browsing this forum: andy_wharton_uk, Google [Bot] and 67 guests