gpt4 book ai didi

c - esp32 idf 多路服务器

转载 作者:太空宇宙 更新时间:2023-11-04 03:16:11 25 4
gpt4 key购买 nike

这是我的第一篇文章,所以如果有帮助,我可以远程请求任何东西,但我没有提供。

我的应用程序需要从 Master 一次打开多个套接字,然后从属连接到 WiFi,然后连接到套接字

问题是:我必须使其“防弹”以防止从奴隶不断重新连接并且我收到接受错误:E (23817) TCP 套接字:接受错误:-1 系统中打开的文件太多它出现在我第 5 次重新连接客户端时,当 menuconfig 中的 Max Number of Open Sockets = 5 时,

当客户端在 1 秒内未发送任何内容时,我会断开客户端与服务器的连接 -> 然后我假设他们得到了 DC-d。我使用 close() 过程来完成。

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]);
}
}

}
}
}

对于每个套接字,我运行 1 个任务,该任务应该从该套接字接收并采取进一步行动。

对于所有这些,我还有一项任务是检查上次消息到达的时间,并在超过时间(2 秒)时重新启动任务

我需要在最终版本中打开大约 16 个套接字,因此没有空间容纳在从站重新启动整个连接后仍在关闭的套接字

  1. 如何正确关闭其中运行 recv() 过程的任务以正确关闭套接字。
  2. 如果 WiFi 没有实现 STA DC-d,有没有办法从服务器端读取套接字已关闭
  3. 这是关于来自 tcp 堆栈的 TIME_WAIT 吗?

套接字读取代码:

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]));
}
}
}
}

最佳答案

我没看到你在任何地方关闭你的套接字?

套接字,不管是什么平台,通常都是一种有限的资源,而且是一种会被重用的资源。如果你不关闭套接字,那么系统会认为你仍然在使用,并且不能将这些套接字重新用于新连接(在 POSIX 系统上,甚至打开文件也会受到影响)。

因此,当不再需要它们时,立即关闭连接。

通常这是通过检查 recvsend 返回的内容来完成的:如果它们返回的值小于零,则会发生错误,并且在大多数情况下这是不可恢复的错误,所以应该关闭连接。即使是可恢复的错误,也更容易关闭连接并让客户端重新连接。

recv 也有返回零的特殊情况。这意味着另一端已关闭连接。那当然你也需要结束你的结局。

关于c - esp32 idf 多路服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51283617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com