You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TwinCat3 TCP/IP随机断开报错32770(Socket handle无效)问题咨询

问题根因及修复方案

错误表现对应核心原因

错误码32770明确表示调用fbSocketReceive时传入的Socket句柄已被释放失效,你的代码存在3处逻辑错误直接触发该问题:

  • 接收超时被误判为致命错误,触发异常断连逻辑
  • 单连接报错后直接关闭监听Socket,导致已建立的连接被底层自动回收
  • 接收功能块的触发逻辑不合理,频繁打断正在执行的接收操作,引发底层Socket状态异常

具体修复方案

1. 修正状态3的接收逻辑

将超时错误和真实异常拆分,忽略无数据的超时场景,仅处理真实连接错误:

3:  // client connected, send and receive data
    // 先重置上一次的错误残留
    bError := FALSE;
    nErrorID := 0;
    
    fbSocketReceive(
        sSrvNetId:='', 
        hSocket:=hSocket, 
        cbLen:=SIZEOF(stDataRx), 
        pDest:=ADR(stDataRx), 
        // 不要频繁翻转Execute,保持电平触发,接收完成后自动进入下一次等待
        bExecute:= TRUE,
        // 缩短超时时间,避免长时间阻塞状态机
        tTimeout:=T#500MS, 
        bBusy=> , 
        bError=>bError, 
        nErrId=>nErrorID,
        nRecBytes=> );
            
    IF NOT fbSocketReceive.bBusy THEN
        // 正常收到数据
        IF fbSocketReceive.nRecBytes > 0                                       
        THEN
            fbSocketSend(bExecute:=FALSE);
            nCntRx:=nCntRx+1;
            bNewDataReceived:=TRUE;
        // 远端主动关闭连接,返回0字节,此时才走断连逻辑
        ELSIF fbSocketReceive.nRecBytes = 0 THEN
            iState:=99;
        // 超时错误直接忽略,下一个周期继续接收即可
        ELSIF bError AND nErrorID = 32769 THEN 
            bError := FALSE;
            nErrorID := 0;
        // 仅非超时的真实错误才走断连逻辑
        ELSIF bError THEN
            iState:=99;
        END IF
    END_IF
                        
    IF NOT bEnable THEN
        iState:=99;
    END_IF

2. 修正错误处理逻辑,不要随意关闭监听Socket

单连接报错不需要关闭监听Socket,避免影响后续新连接接入,也不会导致现有连接被底层回收:

99: // 错误处理,仅关闭当前出错的连接Socket,保留监听Socket
    fbSocketClose(                                                         
        sSrvNetId:='', 
        hSocket:=hSocket, 
        bExecute:=TRUE, 
        tTimeout:=T#4S, 
        bBusy=> , 
        bError=>bError, 
        nErrId=>nErrorID);

    IF NOT fbSocketClose.bBusy OR fbSocketClose.bError THEN
        hSocket.handle:=0;
        bConnected:=FALSE;
        // 直接回到等待客户端连接的状态,无需重建监听
        iState:=2;
    END_IF

如果需要支持主动停止服务,可以额外加单独的状态处理监听Socket的关闭逻辑。

3. 修正fbSocketAccept的触发逻辑

移除bExecute:= bAcceptExecute:= NOT bAcceptExecute的翻转逻辑,在状态2时保持bExecute:=TRUE即可,直到有客户端接入或者报错。


额外验证项

  • 检查PLC TCP栈配置,确认是否开启了空闲连接自动回收,将空闲超时调整到300秒以上
  • 用Wireshark抓包确认断连时FIN包的发送方,如果是Hercules客户端主动发送,检查客户端的保活配置

内容的提问来源于stack exchange,提问作者sharkyenergy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:36:03