Accept Error Multi Socket Server

jurstu
Posts: 3
Joined: Fri Jul 06, 2018 4:37 pm

Accept Error Multi Socket Server

Postby jurstu » Sat Jul 07, 2018 5:23 pm

Hello,

It's my first post so ask for remotely anything if it can help and I didn't provide it.

My application requires multiple sockets being opened at once from Master, then the slaves connect to WiFi, and then to the sockets

Problem is: I have to make it "bulletproof" against constant reconnecting from slaves and i get Accept error:
E (23817) TCP SOCKET: accept error: -1 Too many open files in system
It appears when I reconnect client for 5th time, when Max Number of Open Sockets = 5 in menuconfig,


I disconnect clients from the server when they don't send anything in 1second -> then i assume they got DC-d.
I do it with close() procedure.

Code: Select all

void closeOvertimedTask(void * ignore)
{
	while(1)
	{
		for(int i = 0; i < openedSockets;)
		{
			if(needsRestart[i] == 1)
			{
				ESP_LOGI("RESTARTING", " task#%d",i);
				//lwip_close_r(clientSock[i]);

				//closesocket(clientSock[i]);

				//ESP_LOGI("closing result", "%d", close(clientSock[i]));
				stopSocketHandler(i);
				needsRestart[i] = 0;
				//if(isSocketOpened[i])
				{
					
				}

				ESP_LOGI("close", "%d", lwip_close_r(clientSock[i]));
				isSocketOpened[i] = 0;

				xTaskCreate( handleNthSocket, "TCP_HANDLER", 10*1024, &(sockNums[i]) , tskIDLE_PRIORITY, &socketHandlerHandle[i]);
				configASSERT(socketHandlerHandle[i]);
				needsRestart[i] = 0;
			}

			if(isSocketOpened[i])
			{
				int diff = ((int)((uint64_t)esp_timer_get_time()) - lastWDT[i]) - 2*TCPWDT;

				if(diff > 0)
				{
					if(isSocketOpened[i])
					{
						ESP_LOGI("I FOUND OUT HE DC-d","");
						//closesocket(clientSock[i]);
					}
					ESP_LOGI("close", "%d", close(clientSock[i]));
					
					stopSocketHandler(i);
					isSocketOpened[i] = 0;
			
					xTaskCreate( handleNthSocket, "TCP_HANDLER", 10*1024, &(sockNums[i]) , tskIDLE_PRIORITY, &socketHandlerHandle[i]);
					configASSERT(socketHandlerHandle[i]);
				}
			}
		
		}
	}
}
For each socket I run 1 task that is supposed to receive from that socket and act further.

For all of them I have an other task that checks last time a message arrived and restarts tasks when time has exceeded (it's 2 seconds)

I need around 16 sockets opened in the final version so there is no room to have sockets that are still closing after Slave has restarted whole connection

1. How to properly close a Task with running recv() procedure in it to properly close Socket.
2. Is there a way to read from Server side that socket has been closed if WiFi hasn't realized STA DC-d
3. Is this about TIME_WAIT from tcp stack ?


Socket read code:

Code: Select all

void handleNthSocket(void * param) // 0 <= whichSocket < openedSockets 
{
	int whichSocket =  *((int *) param);

	ESP_LOGI("TCP SOCKET", "%s     #%d", getSpaces(whichSocket), whichSocket);
	struct sockaddr_in clientAddress;

	while (1) 
	{
		if(needsRestart [whichSocket] == 0)
		{
			socklen_t clientAddressLength = sizeof(clientAddress);
			clientSock[whichSocket] = accept(sock[whichSocket], (struct sockaddr *)&clientAddress, &clientAddressLength);
			if (clientSock[whichSocket] < 0) 
			{
				ESP_LOGE("TCP SOCKET", "accept error: %d %s", clientSock[whichSocket], strerror(errno));  //HERE IT FLIPS
				//E (232189) TCP SOCKET: accept error: -1 Too many open files in system

				isSocketOpened[whichSocket] = 0;
				needsRestart[whichSocket] = 1;
				continue;
			}
			//isSocketOpened[whichSocket] = 1;
			// We now have a new client ...
	
			int total = 1000;

			char dataNP[1000];
			char *data;
			data = &dataNP[0];

			for(int z = 0; z < total; z++)
			{
				dataNP[z] = 0;
			} 
			ESP_LOGI("TCP SOCKET", "%snew client",getSpaces(whichSocket));
			ESP_LOGI("          ", "%s#%d connected",getSpaces(whichSocket), whichSocket);
			lastWDT[whichSocket] = (uint64_t)esp_timer_get_time() + 1000000;
			isSocketOpened[whichSocket] = 1;
			// Loop reading data.
	
	
			while(isSocketOpened[whichSocket]) 
			{
				/*
				if (sizeRead < 0) 
				{
					ESP_LOGE(tag, "recv: %d %s", sizeRead, strerror(errno));				
					goto END;
				}

				if (sizeRead == 0) 
				{
					break;
				}
				sizeUsed += sizeRead;
				*/

				ssize_t sizeRead = recv(clientSock[whichSocket], data, total, 0);
				/*for (int k = 0; k < sizeRead; k++)
				{
					if(*(data+k) == '\n')
					{
						ESP_LOGI("TCP DATA  ", "%sthere was enter", getSpaces(whichSocket));
						//ESP_LOGI("TIME      ", "%d", (int)esp_timer_get_time());
					}
					//ESP_LOGI("last wdt", "%d", (int)lastWDT[whichSocket]);
					
				}*/

	
				lastWDT[whichSocket] = (uint64_t)esp_timer_get_time();
				int diff = ((int)((uint64_t)esp_timer_get_time()) - lastWDT[whichSocket]) - 2*TCPWDT;
				ESP_LOGI("last wdt", "%d, data = %s", (int)lastWDT[whichSocket], data);
				
				if(diff > 0)
				{
					ESP_LOGI("last wdt", "too long - %d", diff);
					isSocketOpened[whichSocket] = 0;
				}
				
				if (sizeRead < 0)
				{
					isSocketOpened[whichSocket] = 0;
				}


				//TODO: all RX from slave routine
				for(int k = 0; k < sizeRead; k++)
				{
					*(data+k) = 0;
				}


	
	//			ESP_LOGI("lol data", "clientSock[whichSocket]=%d, 
				/*if(sizeRead > -1)
				{
					ESP_LOGI("TCP DATA: ", "%c", *(data + sizeRead-1));
				}
				else
				{
					ESP_LOGI("TCP DC    ", "");
					goto END;				
				}*/		

				

			}
			if(isSocketOpened[whichSocket])
			{
				ESP_LOGI("closing result", "%d", close(clientSock[whichSocket]));
			}
		}		
	}
}

jurstu
Posts: 3
Joined: Fri Jul 06, 2018 4:37 pm

Re: Accept Error Multi Socket Server

Postby jurstu » Wed Jul 11, 2018 1:03 pm

jurstu wrote:Hello,

It's my first post so ask for remotely anything if it can help and I didn't provide it.

My application requires multiple sockets being opened at once from Master, then the slaves connect to WiFi, and then to the sockets

Problem is: I have to make it "bulletproof" against constant reconnecting from slaves and i get Accept error:
E (23817) TCP SOCKET: accept error: -1 Too many open files in system
It appears when I reconnect client for 5th time, when Max Number of Open Sockets = 5 in menuconfig,


I disconnect clients from the server when they don't send anything in 1second -> then i assume they got DC-d.
I do it with close() procedure.

Code: Select all

void closeOvertimedTask(void * ignore)
{
	while(1)
	{
		for(int i = 0; i < openedSockets;)
		{
			if(needsRestart[i] == 1)
			{
				ESP_LOGI("RESTARTING", " task#%d",i);
				//lwip_close_r(clientSock[i]);

				//closesocket(clientSock[i]);

				//ESP_LOGI("closing result", "%d", close(clientSock[i]));
				stopSocketHandler(i);
				needsRestart[i] = 0;
				//if(isSocketOpened[i])
				{
					
				}

				ESP_LOGI("close", "%d", lwip_close_r(clientSock[i]));
				isSocketOpened[i] = 0;

				xTaskCreate( handleNthSocket, "TCP_HANDLER", 10*1024, &(sockNums[i]) , tskIDLE_PRIORITY, &socketHandlerHandle[i]);
				configASSERT(socketHandlerHandle[i]);
				needsRestart[i] = 0;
			}

			if(isSocketOpened[i])
			{
				int diff = ((int)((uint64_t)esp_timer_get_time()) - lastWDT[i]) - 2*TCPWDT;

				if(diff > 0)
				{
					if(isSocketOpened[i])
					{
						ESP_LOGI("I FOUND OUT HE DC-d","");
						//closesocket(clientSock[i]);
					}
					ESP_LOGI("close", "%d", close(clientSock[i]));
					
					stopSocketHandler(i);
					isSocketOpened[i] = 0;
			
					xTaskCreate( handleNthSocket, "TCP_HANDLER", 10*1024, &(sockNums[i]) , tskIDLE_PRIORITY, &socketHandlerHandle[i]);
					configASSERT(socketHandlerHandle[i]);
				}
			}
		
		}
	}
}
For each socket I run 1 task that is supposed to receive from that socket and act further.

For all of them I have an other task that checks last time a message arrived and restarts tasks when time has exceeded (it's 2 seconds)

I need around 16 sockets opened in the final version so there is no room to have sockets that are still closing after Slave has restarted whole connection

1. How to properly close a Task with running recv() procedure in it to properly close Socket.
2. Is there a way to read from Server side that socket has been closed if WiFi hasn't realized STA DC-d
3. Is this about TIME_WAIT from tcp stack ?


Socket read code:

Code: Select all

void handleNthSocket(void * param) // 0 <= whichSocket < openedSockets 
{
	int whichSocket =  *((int *) param);

	ESP_LOGI("TCP SOCKET", "%s     #%d", getSpaces(whichSocket), whichSocket);
	struct sockaddr_in clientAddress;

	while (1) 
	{
		if(needsRestart [whichSocket] == 0)
		{
			socklen_t clientAddressLength = sizeof(clientAddress);
			clientSock[whichSocket] = accept(sock[whichSocket], (struct sockaddr *)&clientAddress, &clientAddressLength);
			if (clientSock[whichSocket] < 0) 
			{
				ESP_LOGE("TCP SOCKET", "accept error: %d %s", clientSock[whichSocket], strerror(errno));  //HERE IT FLIPS
				//E (232189) TCP SOCKET: accept error: -1 Too many open files in system

				isSocketOpened[whichSocket] = 0;
				needsRestart[whichSocket] = 1;
				continue;
			}
			//isSocketOpened[whichSocket] = 1;
			// We now have a new client ...
	
			int total = 1000;

			char dataNP[1000];
			char *data;
			data = &dataNP[0];

			for(int z = 0; z < total; z++)
			{
				dataNP[z] = 0;
			} 
			ESP_LOGI("TCP SOCKET", "%snew client",getSpaces(whichSocket));
			ESP_LOGI("          ", "%s#%d connected",getSpaces(whichSocket), whichSocket);
			lastWDT[whichSocket] = (uint64_t)esp_timer_get_time() + 1000000;
			isSocketOpened[whichSocket] = 1;
			// Loop reading data.
	
	
			while(isSocketOpened[whichSocket]) 
			{
				/*
				if (sizeRead < 0) 
				{
					ESP_LOGE(tag, "recv: %d %s", sizeRead, strerror(errno));				
					goto END;
				}

				if (sizeRead == 0) 
				{
					break;
				}
				sizeUsed += sizeRead;
				*/

				ssize_t sizeRead = recv(clientSock[whichSocket], data, total, 0);
				/*for (int k = 0; k < sizeRead; k++)
				{
					if(*(data+k) == '\n')
					{
						ESP_LOGI("TCP DATA  ", "%sthere was enter", getSpaces(whichSocket));
						//ESP_LOGI("TIME      ", "%d", (int)esp_timer_get_time());
					}
					//ESP_LOGI("last wdt", "%d", (int)lastWDT[whichSocket]);
					
				}*/

	
				lastWDT[whichSocket] = (uint64_t)esp_timer_get_time();
				int diff = ((int)((uint64_t)esp_timer_get_time()) - lastWDT[whichSocket]) - 2*TCPWDT;
				ESP_LOGI("last wdt", "%d, data = %s", (int)lastWDT[whichSocket], data);
				
				if(diff > 0)
				{
					ESP_LOGI("last wdt", "too long - %d", diff);
					isSocketOpened[whichSocket] = 0;
				}
				
				if (sizeRead < 0)
				{
					isSocketOpened[whichSocket] = 0;
				}


				//TODO: all RX from slave routine
				for(int k = 0; k < sizeRead; k++)
				{
					*(data+k) = 0;
				}


	
	//			ESP_LOGI("lol data", "clientSock[whichSocket]=%d, 
				/*if(sizeRead > -1)
				{
					ESP_LOGI("TCP DATA: ", "%c", *(data + sizeRead-1));
				}
				else
				{
					ESP_LOGI("TCP DC    ", "");
					goto END;				
				}*/		

				

			}
			if(isSocketOpened[whichSocket])
			{
				ESP_LOGI("closing result", "%d", close(clientSock[whichSocket]));
			}
		}		
	}
}
CHANGE: this post solved all my problems
https://esp32.com/viewtopic.php?t=911

Who is online

Users browsing this forum: Google [Bot] and 126 guests