TwinCat3 — TCP/IP отключается случайным образом

#sockets #tcp #handle #twincat

Вопрос:

Я использую следующий код для настройки сервера TCP IP. Я подключаюсь к нему со своего ноутбука с помощью hercules. По непонятной мне причине он отключается через случайное количество секунд между 1 и 20. Ошибка, которую я получаю, — «Дескриптор сокета недопустим» (32770) в fbSocketReceive.

Чего бы я ожидал:

цикл должен оставаться на шаге 3 и оставаться подключенным, если соединение не закрыто удаленно или кабель не отсоединен. Если что-то отправлено, оно должно быть обработано.

Что происходит:

цикл остается на шаге 3, как только клиент подключается, и через случайное количество секунд (от 1 до 20) Я получаю ошибку 32770 в fbSocketReceive.

Я не могу понять, почему он теряет дескриптор сокета…

     // Init Step to close all sockets after login PLC with download or when starting PLC
    IF bInit
    THEN
        fbSocketCloseAll(
            sSrvNetId:='', 
            bExecute:=TRUE, 
            tTimeout:=T#3S, 
            bBusy=> , 
            bError=>bSocketCloseError, 
            nErrId=>nSocketCloseError);
        IF NOT (fbSocketCloseAll.bBusy OR fbSocketCloseAll.bError)
        THEN
            bInit:=FALSE;
            fbSocketCloseAll(bExecute:=FALSE);
        END_IF
        RETURN;
    END_IF
    
// Reset Flag
    IF bDataTxChanged
    THEN
        bDataTxChanged:=FALSE;
    END_IF
    
// Reset Flag
    IF bNewDataReceived
    THEN
        bNewDataReceived:=FALSE;
    END_IF



// Cycle
    CASE iState OF
        
        0:  // Init State
        
            IF bEnable
            THEN
                fbSocketListen(bExecute:=FALSE);
                fbSocketAccept(bExecute:=FALSE);
                fbSocketCloseAll(bExecute:=FALSE);
                fbSocketClose(bExecute:=FALSE);
                bBusy:=TRUE;
                iState:=1;
            ELSE
                bBusy:=FALSE;
            END_IF

        1:  // Open Listener-Socket

            fbSocketListen(
                sSrvNetId:='', 
                sLocalHost:=sLocalHost, 
                nLocalPort:=nLocalPort, 
                bExecute:=TRUE, 
                tTimeout:=T#14S, 
                bBusy=> , 
                bError=>bError, 
                nErrId=>nErrorID,
                hListener=>hListener);

            IF hListener.handle <> 0
            THEN
                iState:=2;
            ELSIF bError
            THEN
                iState:=99;
            END_IF

        2:  // Accept Client connection

            fbSocketAccept(
                sSrvNetId:='', 
                hListener:=hListener, 
                bExecute:= bAcceptExecute:= NOT bAcceptExecute, 
                tTimeout:=T#14S, 
                bAccepted=> , 
                bBusy=> , 
                bError=>bError, 
                nErrId=>nErrorID,
                hSocket=>hSocket);

            IF bError
            THEN
                iState:=99;
            ELSIF hSocket.handle <> 0
            THEN
                iState:=3;
                bConnected:=TRUE;
            END_IF

        3:  // client connected, send and receive data
            
            fbSocketReceive(
                sSrvNetId:='', 
                hSocket:=hSocket, 
                cbLen:=SIZEOF(stDataRx), 
                pDest:=ADR(stDataRx), 
                bExecute:= bReceiveExecute:= NOT bReceiveExecute,                   // Check for new client telegrams every second cycle
                tTimeout:=T#4S, 
                bBusy=> , 
                bError=>bError, 
                nErrId=>nErrorID,
                nRecBytes=> );
                    
            IF fbSocketReceive.nRecBytes <> 0                                       // Switch to send-state when data are received
            THEN
                fbSocketSend(bExecute:=FALSE);
                nCntRx:=nCntRx 1;
                bNewDataReceived:=TRUE;
            END_IF
                                
            IF fbSocketReceive.bError OR(NOT bEnable)                           // Close connection when error is occuring or trigger is set                    
            THEN
                iState:=99;
            END_IF


        99: // Error Handling

            fbSocketClose(                                                          // Close Listener-Socket
                sSrvNetId:='', 
                hSocket:=hListener, 
                bExecute:=TRUE, 
                tTimeout:=T#4S, 
                bBusy=> , 
                bError=>bError, 
                nErrId=>nErrorID);

            IF (NOT fbSocketClose.bBusy) OR fbSocketClose.bError
            THEN
                hListener.handle:=0;
                iState:=100;
            END_IF

        100:

            fbSocketClose(bExecute := FALSE);
            iState:=101;

        101:
            fbSocketClose(                                                          // Close Connection Socket
                sSrvNetId:='', 
                hSocket:=hSocket, 
                bExecute:=TRUE, 
                tTimeout:=T#4S, 
                bBusy=> , 
                bError=>bError, 
                nErrId=>nErrorID);

            IF NOT (fbSocketClose.bBusy) OR fbSocketClose.bError THEN
                hSocket.handle:=0;  
                iState:=0;
                bConnected:=FALSE;
            END_IF

    END_CASE
 

Ответ №1:

Я нашел проблему.

В другом FB использовался FB Tcp_CloseAllSocket. это также убило сокеты из этого FB.