#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.