IF terminate=FALSE THEN
CASE tcp_state OF
0:
socketId:=SysSockCreate(iAddressFamily:=SOCKET_AF_INET , diType:=SOCKET_STREAM , diProtocol:=SOCKET_IPPROTO_TCP , pResult:=ADR(Error_code));
IF socketId <> -1 THEN
dwValue := 1;
(Set the option that we can reuse 'old' port addresses )
SysSockSetOption(socketId, SOCKET_SOL, SOCKET_SO_REUSEADDR, ADR(dwValue), SIZEOF (dwValue));
tcp_state := 10;
END_IF
10:
bResult := SysSockBind(socketId, ADR(Address_server), AServer_size);
IF UDINT_TO_BOOL(bResult) THEN
tcp_state := 20;
END_IF
20:
Socket_listen := SysSockListen(socketId, 255);
IF Socket_listen=0 THEN
MasterSocketList.fd_count := 1;
MasterSocketList.fd_array[0] := socketId;
tcp_state := 30;
END_IF
// set TCP connection
_TCPConnection(
xEnable:= _TCPServer.xBusy AND NOT(_TCPConnection.xDone), //when server is ready
xDone=> , // client manually disconnected
xBusy=> ,
xError=> ,
hServer:= _TCPServer.hServer, // point all connections back to the same server
eError=> ,
xActive=> ,
hConnection=> _TCPConnection_hConnection);
// only execute on active connections
IF(_TCPConnection.xActive) THEN
// write when connection is ready
_TCPWrite(
xExecute:= _TCPWriteEn, //manually enable for testing
udiTimeOut:= 600000, //in microseconds => 600ms
xDone=> ,
xBusy=> ,
xError=> ,
hConnection := _TCPConnection_hConnection,
szSize := INT_TO_UINT(LEN(_sTCPSendData)), // write length only
pData := ADR(_sTCPSendData),
eError=> );
//reset write enable
IF(_TCPWrite.xDone) THEN
_TCPWriteEn:= FALSE;
END_IF
// read when connection is ready
_TCPRead(
xEnable:= TRUE,
xDone=> ,
xBusy=> ,
xError=> ,
hConnection:= _TCPConnection_hConnection,
szSize:= SIZEOF(_sTCPReadData),
pData:= ADR(_sTCPReadData),
eError=> ,
xReady=> ,
szCount=> );
ELSE
// no connection made
_TCPRead.xEnable:= FALSE;
_TCPWrite.xExecute:= FALSE;
END_IF
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I write the TCP server code on Codesys.
But I meet some problem.
The SysSockSend() work well .
Only power cycle , the server will works well again.
Why ?
PROGRAM TCP_SERVER
VAR
Address_server: SOCKADDRESS;
AServer_size: UINT;
i_udIPdescription_client: UDINT;
Client_port: INT := 8000;
AClient_size: UINT;
i_udIPdescription: UDINT;
Server_port: INT := 8001;
PLC_IP: STRING := '192.168.1.10';
ClientIP: STRING := '192.168.1.22';
terminate: BOOL;
tcp_state: INT;
socketId: UDINT;
dwValue: INT;
bResult: SYSSOCKET.RTS_IEC_RESULT;
SelectTimeOut: SYSSOCKET.SOCKET_TIMEVAL;
SlaveSocketList: SYSSOCKET.SOCKET_FD_SET;
MasterSocketList:SYSSOCKET.SOCKET_FD_SET;
diSize: DINT;
Socket_listen: SYSSOCKET.RTS_IEC_RESULT;
TCPindex: INT;
SocketHandle: RTS_IEC_HANDLE;
TCPMax: RTS_IEC_HANDLE;
SysSockRecv_result: RTS_IEC_RESULT;
SysSocketSend_Result: RTS_IEC_RESULT;
result: BOOL;
Temp_SockerId: SYSSOCKET.RTS_IEC_HANDLE;
Error_code: UDINT;
Accept_ErrorCode: UDINT;
ServerAddress_Des: UDINT;
ClientAddress_Des: UDINT;
Connect_number: SYSSOCKET.RTS_IEC_RESULT;
receive_Data: array [ 1..512] of BYTE;
send_data: array [1..512] of BYTE;
END_VAR
Address_server.sin_addr.ulAddr:=SysSockInetAddr(szIPAddress:=PLC_IP , pInAddr:= ADR(ServerAddress_Des));
Address_server.sin_family:=SOCKET_AF_INET;
Address_server.sin_port:=SysSockHtons(Server_port);
AServer_size:= SIZEOF (Address_server);
IF terminate=FALSE THEN
CASE tcp_state OF
0:
socketId:=SysSockCreate(iAddressFamily:=SOCKET_AF_INET , diType:=SOCKET_STREAM , diProtocol:=SOCKET_IPPROTO_TCP , pResult:=ADR(Error_code));
IF socketId <> -1 THEN
dwValue := 1;
(Set the option that we can reuse 'old' port addresses )
SysSockSetOption(socketId, SOCKET_SOL, SOCKET_SO_REUSEADDR, ADR(dwValue), SIZEOF (dwValue));
tcp_state := 10;
END_IF
10:
bResult := SysSockBind(socketId, ADR(Address_server), AServer_size);
IF UDINT_TO_BOOL(bResult) THEN
tcp_state := 20;
END_IF
20:
Socket_listen := SysSockListen(socketId, 255);
IF Socket_listen=0 THEN
MasterSocketList.fd_count := 1;
MasterSocketList.fd_array[0] := socketId;
tcp_state := 30;
END_IF
30:
SlaveSocketList:=MasterSocketList;
SelectTimeOut.tv_sec := 0;
SelectTimeOut.tv_usec := 5000;
Connect_number:=SysSockSelect(
diWidth:=SOCKET_FD_SETSIZE ,
pfdRead:=ADR(SlaveSocketList) ,
pfdWrite:=0 ,
pfdExcept:=0 ,
ptvTimeout:= ADR(SelectTimeOut) ,
pdiReady:=ADR(diSize ));
//SysSockSelect(SOCKET_FD_SETSIZE, ADR(SlaveSocketList), 0, 0, ADR(SelectTimeOut));
IF Connect_number > 0 THEN
tcp_state := 50;
TCPindex := 0;
END_IF
50:
//SocketHandle := SlaveSocketList.fd_array[TCPindex];
SocketHandle:=SysSockAccept(hSocket:=socketId , pSockAddr:=ADR(Address_server) , pdiSockAddrSize:=ADR(AServer_size) , pResult:=ADR(Accept_ErrorCode));
//SysSockAccept(socketId, ADR(Address), ADR(address));
IF SocketHandle <> -1 THEN
TCPMax := SocketHandle;
MasterSocketList.fd_array[MasterSocketList.fd_count] := SocketHandle;
MasterSocketList.fd_count := MasterSocketList.fd_count + 1;
END_IF
tcp_state := 100;
100:
( SysSockSend(socketId,ADR(send),SIZEOF(send),1);)
SysSockRecv(
hSocket:=socketId ,
pbyBuffer:=ADR(receive_Data) ,
diBufferSize:= SIZEOF(receive_Data),
diFlags:=1,
pResult:=ADR(SysSockRecv_result));
tcp_state := 120;
120:
SysSockSend(
hSocket:=SocketHandle ,
pbyBuffer:=ADR(send_data) ,
diBufferSize:=(write_len-1+6),
diFlags:=1 ,
pResult:=ADR(SysSocketSend_Result) );
receive1[1]:=0;
send_do:=FALSE;
tcp_state := 100;
END_CASE;
END_IF;
IF terminate = TRUE THEN ( close socket )
SysSockClose(socketId);
socketId := 0;
tcp_state:=0;
result := FALSE;
END_IF
receive1[1]:=0;
send_do:=FALSE;
tcp_state := 100;
END_CASE;
END_IF;
IF terminate = TRUE THEN ( close socket )
SysSockClose(socketId);
socketId := 0;
tcp_state:=0;
result := FALSE;
END_IF
I would highly recommend you install the Network library instead. Then use these function blocks which will make your life much easier.:
VAR
// =======================================
// set up server
// =======================================
_TCPServer : NBS.TCP_Server;
_TCPServer_ipAddr: NBS.IP_ADDR;
_TCPServer_uiPort: UINT:= uiPort;
_TCPServer_hServer : CAA.HANDLE; // server handle
_sServerIP : STRING(15):='192.168.1.100'; ( this device's server IP address )
_uiPort : UINT:= 10000;
_TCPConnection : NBS.TCP_Connection; // TCP connection instances
_TCPConnection_hConnection: CAA.HANDLE; // handle of client connections
_TCPWrite : NBS.TCP_Write; // TCP write
_TCPRead : NBS.TCP_Read; // TCP read
_sTCPSendData: STRING:= 'Hello World';
_sTCPReadData: STRING(1000); //receive up to 1000 chars if needed
END_VAR
PROGRAM:
_TCPServer_ipAddr.sAddr := _sServerIP; //set IP address
_TCPServer(
xEnable:= , // manually toggle for testing
xDone=> ,
xBusy=> ,
xError=> ,
ipAddr:= _TCPServer_ipAddr,
uiPort:= _uiPort,
eError=> ,
hServer=> _TCPServer_hServer);
// set TCP connection
_TCPConnection(
xEnable:= _TCPServer.xBusy AND NOT(_TCPConnection.xDone), //when server is ready
xDone=> , // client manually disconnected
xBusy=> ,
xError=> ,
hServer:= _TCPServer.hServer, // point all connections back to the same server
eError=> ,
xActive=> ,
hConnection=> _TCPConnection_hConnection);
// only execute on active connections
IF(_TCPConnection.xActive) THEN
// write when connection is ready
_TCPWrite(
xExecute:= _TCPWriteEn, //manually enable for testing
udiTimeOut:= 600000, //in microseconds => 600ms
xDone=> ,
xBusy=> ,
xError=> ,
hConnection := _TCPConnection_hConnection,
szSize := INT_TO_UINT(LEN(_sTCPSendData)), // write length only
pData := ADR(_sTCPSendData),
eError=> );
//reset write enable
IF(_TCPWrite.xDone) THEN
_TCPWriteEn:= FALSE;
END_IF
// read when connection is ready
_TCPRead(
xEnable:= TRUE,
xDone=> ,
xBusy=> ,
xError=> ,
hConnection:= _TCPConnection_hConnection,
szSize:= SIZEOF(_sTCPReadData),
pData:= ADR(_sTCPReadData),
eError=> ,
xReady=> ,
szCount=> );
ELSE
// no connection made
_TCPRead.xEnable:= FALSE;
_TCPWrite.xExecute:= FALSE;
END_IF