首页 > 解决方案 > TwinCat3 - TCP/IP 随机断开连接

问题描述

我正在使用以下代码来设置 TCP IP 服务器。我正在使用 hercules 从我的笔记本电脑连接到它。由于我不明白的原因,它在 1 到 20 之间的随机秒数后断开连接。我得到的错误是 fbSocketReceive 上的“套接字句柄无效”(32770)。

我所期望的:

循环应停留在第 3 步,并保持连接,除非远程关闭连接或断开电缆。如果发送了某些内容,则应该对其进行处理。

怎么了:

一旦客户端连接,循环就会停留在第 3 步,并且在随机数秒(1 到 20 秒)后,我在 fbSocketReceive 上收到 32770 错误。

我无法弄清楚为什么它会丢失 Socket 句柄......

    // 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

标签: socketstcphandletwincat

解决方案


我发现了问题。

在另一个 FB 中,使用了 FB Tcp_CloseAllSocket。这也杀死了这个 FB 的套接字。


推荐阅读