1

これは私の最初の投稿なので、それが役立つかどうかをリモートで尋ねますが、私はそれを提供しませんでした.

私のアプリケーションでは、マスターから一度に複数のソケットを開く必要があり、スレーブは WiFi に接続し、次にソケットに接続します。

問題は次のとおりです。スレーブからの絶え間ない再接続に対して「防弾」にする必要があり、Accept error: E (23817) TCP SOCKET: accept error: -1 Too many open files in system クライアントを 5 回再接続すると表示されます。 menuconfig で 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]));
            }
        }       
    }
}
4

2 に答える 2