TwinCat3 - TCP/IP 随机断开连接
TwinCat3 - TCP/IP disconnects randomly
我正在使用以下代码设置 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
我找到问题了。
在另一个FB中,使用了FBTcp_CloseAllSocket。这也杀死了这个 FB 的套接字。
我正在使用以下代码设置 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
我找到问题了。
在另一个FB中,使用了FBTcp_CloseAllSocket。这也杀死了这个 FB 的套接字。