TwinCAT 3 tcp程序

ST   ENUM    UNION

TYPE ENUM_tcp_client :
(
	nInitial:=0,
	nConnect,
	nWhetherConnect,
	nDetermineAction,
	nSend,
	nWhetherSend,
	nReceive,
	nWhetherReceive,
	nClose,
	nWhetherClose
);
END_TYPE

TYPE ENUM_tcp_server :
(
	nInitial:=0,
	nListen,
	nWhetherListen,
	nAccept,
	nWhetherAccept,
	nDetermineAction,
	nSend,
	nWhetherSend,
	nReceive,
	nWhetherReceive,
	nCloseAll,
	nWhetherCloseAll
);
END_TYPE

TYPE UNION_tcp_hex_char :
UNION
	nByte:ARRAY[0..255] OF BYTE;
	sString:STRING(256);
END_UNION
END_TYPE

TYPE ST_tcp_client :
STRUCT
	control:ST_tcp_client_control;
	parameter:ST_tcp_parameter;
	status:ST_tcp_client_status;
	FB:FB_tcp_client;
END_STRUCT
END_TYPE

TYPE ST_tcp_client_control :
STRUCT
	bConnect:BOOL;
	bReceive:BOOL;
	bSend:BOOL;
	bClose:BOOL;
END_STRUCT
END_TYPE

TYPE ST_tcp_client_status :
STRUCT
	bConnectDone:BOOL;
	bReceiveDone:BOOL;
	bSendDone:BOOL;
	bCloseDone:BOOL;
END_STRUCT
END_TYPE

TYPE ST_tcp_parameter :
STRUCT
	sIp:T_IPv4Addr;
	nPort:UDINT;

	SendData:UNION_tcp_hex_char;
	nSendDataLength:UINT:=256;

	ReceiveData:UNION_tcp_hex_char;
	nReceiveDataLength:UINT:=256;
END_STRUCT
END_TYPE


TYPE ST_tcp_server :
STRUCT
	control:ST_tcp_server_control;
	parameter:ST_tcp_parameter;
	status:ST_tcp_server_status;
	FB:FB_tcp_server;
END_STRUCT
END_TYPE

TYPE ST_tcp_server_control :
STRUCT
	bListen:BOOL;
	bReceive:BOOL;
	bSend:BOOL;
	bCloseAll:BOOL;
END_STRUCT
END_TYPE

TYPE ST_tcp_server_status :
STRUCT
	bListenDone:BOOL;
	bAcceptAccepted:BOOL;
	bReceiveDone:BOOL;
	bSendDone:BOOL;
	bCloseAllDone:BOOL;
END_STRUCT
END_TYPE

FB_tcp_client

FUNCTION_BLOCK FB_tcp_client
VAR_INPUT
	TcpClientControl:ST_tcp_client_control;
END_VAR
VAR_IN_OUT
	TcpClientParameter:ST_tcp_parameter;
END_VAR
VAR_OUTPUT
	TcpClientStatus:ST_tcp_client_status;
END_VAR
VAR
	nClientStep:INT;

	hSocket:T_HSOCKET;
	nReceiveBytes:UDINT;
	i:UDINT;

	SocketConnect:FB_SocketConnect;
	SocketReceive:FB_SocketReceive;
	SocketSend:FB_SocketSend;
	SocketClose:FB_SocketClose;
END_VAR
CASE nClientStep OF
	ENUM_tcp_client.nInitial://复位信号
		SocketConnect.bExecute:=FALSE;
		SocketReceive.bExecute:=FALSE;
		SocketSend.bExecute:=FALSE;
		SocketClose.bExecute:=FALSE;

		TcpClientStatus.bConnectDone:=FALSE;
		TcpClientStatus.bReceiveDone:=FALSE;
		TcpClientStatus.bSendDone:=FALSE;
		TcpClientStatus.bCloseDone:=FALSE;

		IF TcpClientControl.bConnect THEN
			nClientStep:=ENUM_tcp_client.nConnect;
		END_IF
	ENUM_tcp_client.nConnect://连接服务器
		SocketConnect.bExecute:=TRUE;
		IF SocketConnect.bBusy THEN
			SocketConnect.bExecute:=FALSE;
			nClientStep:=ENUM_tcp_client.nWhetherConnect;
		END_IF
	ENUM_tcp_client.nWhetherConnect://判断是否连接成功
		IF SocketConnect.bError THEN
			nClientStep:=ENUM_tcp_client.nInitial;
		END_IF
		IF NOT SocketConnect.bBusy AND NOT SocketConnect.bError THEN
			TcpClientStatus.bConnectDone:=TRUE;
			nClientStep:=ENUM_tcp_client.nDetermineAction;
		END_IF
	ENUM_tcp_client.nDetermineAction://判断动作
		TcpClientStatus.bSendDone:=FALSE;
		TcpClientStatus.bReceiveDone:=FALSE;
		IF TcpClientControl.bClose THEN
			nClientStep:=ENUM_tcp_client.nClose;
		ELSIF TcpClientControl.bSend THEN
			nClientStep:=ENUM_tcp_client.nSend;
		ELSE
			nClientStep:=ENUM_tcp_client.nReceive;
		END_IF
		
	ENUM_tcp_client.nReceive://接收数据
		SocketReceive.bExecute:=TRUE;
		IF SocketReceive.bBusy THEN
			SocketReceive.bExecute:=FALSE;
			nClientStep:=ENUM_tcp_client.nWhetherReceive;
		END_IF
	ENUM_tcp_client.nWhetherReceive://判断是否接收成功
		IF SocketReceive.bError THEN
			nClientStep:=ENUM_tcp_client.nClose;
		END_IF
		IF NOT SocketReceive.bBusy AND NOT SocketReceive.bError THEN
			IF nReceiveBytes>0 THEN
				TcpClientStatus.bReceiveDone:=TRUE;
				nClientStep:=ENUM_tcp_client.nDetermineAction;
			ELSE
				nClientStep:=ENUM_tcp_client.nDetermineAction;
			END_IF
		END_IF
		
	ENUM_tcp_client.nSend://发送数据
		SocketSend.bExecute:=TRUE;
		IF SocketSend.bBusy THEN
			SocketSend.bExecute:=FALSE;
			nClientStep:=ENUM_tcp_client.nWhetherSend;
		END_IF
	ENUM_tcp_client.nWhetherSend://判断是否发送成功
		IF SocketSend.bError THEN
			nClientStep:=ENUM_tcp_client.nClose;
		END_IF
		IF NOT SocketSend.bBusy AND NOT SocketSend.bError THEN
			TcpClientStatus.bSendDone:=TRUE;
			nClientStep:=ENUM_tcp_client.nDetermineAction;
		END_IF
	
	ENUM_tcp_client.nClose://断开连接
		SocketClose.bExecute:=TRUE;
		IF SocketClose.bBusy THEN
			SocketClose.bExecute:=FALSE;
			nClientStep:=ENUM_tcp_client.nWhetherClose;
		END_IF
	ENUM_tcp_client.nWhetherClose://判断是否断开连接
		IF SocketClose.bError THEN
			nClientStep:=ENUM_tcp_client.nInitial;
		END_IF
		IF NOT SocketClose.bBusy AND NOT SocketClose.bError THEN
			TcpClientStatus.bConnectDone:=FALSE;
			TcpClientStatus.bReceiveDone:=FALSE;
			TcpClientStatus.bSendDone:=FALSE;
			TcpClientStatus.bCloseDone:=TRUE;
			nClientStep:=ENUM_tcp_client.nInitial;
		END_IF
END_CASE

//功能块
SocketConnect(
	sSrvNetId:='' , 
	sRemoteHost:=TcpClientParameter.sIp , 
	nRemotePort:=TcpClientParameter.nPort , 
	bExecute:= , 
	tTimeout:=T#10S , 
	bBusy=> , 
	bError=> , 
	nErrId=> , 
	hSocket=>hSocket );

SocketReceive(
	sSrvNetId:='' , 
	hSocket:=hSocket , 
	cbLen:=TcpClientParameter.nReceiveDataLength , 
	pDest:=ADR(TcpClientParameter.ReceiveData) , 
	bExecute:= , 
	tTimeout:=T#10S , 
	bBusy=> , 
	bError=> , 
	nErrId=> , 
	nRecBytes=>nReceiveBytes );
IF nReceiveBytes>0 THEN
	TcpClientParameter.ReceiveData.sString:=LEFT(TcpClientParameter.ReceiveData.sString,UDINT_TO_INT(nReceiveBytes));
	FOR i:=nReceiveBytes TO 255 BY 1 DO
		TcpClientParameter.ReceiveData.nByte[i]:=0;
	END_FOR
END_IF

IF SocketSend.bExecute THEN
	FOR i:=TcpClientParameter.nSendDataLength TO 255 BY 1 DO
		TcpClientParameter.SendData.nByte[i]:=0;
	END_FOR
END_IF
SocketSend(
	sSrvNetId:='' , 
	hSocket:=hSocket , 
	cbLen:=TcpClientParameter.nSendDataLength , 
	pSrc:=ADR(TcpClientParameter.SendData) , 
	bExecute:= , 
	tTimeout:=T#10S , 
	bBusy=> , 
	bError=> , 
	nErrId=> );	
	
SocketClose(
	sSrvNetId:='' , 
	hSocket:=hSocket , 
	bExecute:= , 
	tTimeout:=T#10S , 
	bBusy=> , 
	bError=> , 
	nErrId=> );

FB_tcp_server

FUNCTION_BLOCK FB_tcp_server
VAR_INPUT
	TcpServerControl:ST_tcp_server_control;
END_VAR
VAR_IN_OUT
	TcpServerParameter:ST_tcp_parameter;
END_VAR
VAR_OUTPUT
	TcpServerStatus:ST_tcp_server_status;
END_VAR
VAR
	nServerStep:INT;

	hListener:T_HSOCKET;
	hSocket:T_HSOCKET;
	nReceiveBytes:UDINT;
	i:UDINT;

	SocketListen:FB_SocketListen;
	SocketAccept:FB_SocketAccept;
	SocketReceive:FB_SocketReceive;
	SocketSend:FB_SocketSend;
	SocketCloseAll:FB_SocketCloseAll;
END_VAR
CASE nServerStep OF
	ENUM_tcp_server.nInitial://复位
		SocketListen.bExecute:=FALSE;
		SocketAccept.bExecute:=FALSE;
		SocketSend.bExecute:=FALSE;
		SocketReceive.bExecute:=FALSE;
		SocketCloseAll.bExecute:=FALSE;

		TcpServerStatus.bListenDone:=FALSE;
		TcpServerStatus.bAcceptAccepted:=FALSE;
		TcpServerStatus.bReceiveDone:=FALSE;
		TcpServerStatus.bSendDone:=FALSE;
		TcpServerStatus.bCloseAllDone:=FALSE;

		IF TcpServerControl.bListen THEN
			nServerStep:=ENUM_tcp_server.nListen;
		END_IF
	ENUM_tcp_server.nListen://打开监听
		SocketListen.bExecute:=TRUE;
		IF SocketListen.bBusy THEN
			SocketListen.bExecute:=FALSE;
			nServerStep:=ENUM_tcp_server.nWhetherListen;
		END_IF
	ENUM_tcp_server.nWhetherListen://判断是否监听成功
		IF SocketListen.bError THEN
			nServerStep:=ENUM_tcp_server.nInitial;
		END_IF
		IF NOT SocketListen.bBusy AND NOT SocketListen.bError THEN
			TcpServerStatus.bListenDone:=TRUE;
			nServerStep:=ENUM_tcp_server.nAccept;
		END_IF
	ENUM_tcp_server.nAccept://接收客户端
		IF TcpServerControl.bCloseAll THEN
			nServerStep:=ENUM_tcp_server.nCloseAll;
		ELSE
			SocketAccept.bExecute:=TRUE;
		END_IF
		IF SocketAccept.bBusy THEN
			SocketAccept.bExecute:=FALSE;
			nServerStep:=ENUM_tcp_server.nWhetherAccept;
		END_IF
	ENUM_tcp_server.nWhetherAccept://判断是否接收到客户端
		IF SocketAccept.bError THEN
			nServerStep:=ENUM_tcp_server.nCloseAll;
		END_IF
		IF NOT SocketAccept.bBusy AND NOT SocketAccept.bError THEN
			IF NOT TcpServerStatus.bAcceptAccepted THEN
				nServerStep:=ENUM_tcp_server.nAccept;
			ELSE
				nServerStep:=ENUM_tcp_server.nDetermineAction;
			END_IF
		END_IF
	ENUM_tcp_server.nDetermineAction://判断动作
		TcpServerStatus.bSendDone:=FALSE;
		TcpServerStatus.bReceiveDone:=FALSE;
		IF TcpServerControl.bCloseAll THEN
			nServerStep:=ENUM_tcp_server.nCloseAll;
		ELSIF TcpServerControl.bSend THEN
			nServerStep:=ENUM_tcp_server.nSend;
		ELSE
			nServerStep:=ENUM_tcp_server.nReceive;
		END_IF

	ENUM_tcp_server.nReceive://接收数据
		SocketReceive.bExecute:=TRUE;
		IF SocketReceive.bBusy THEN
			SocketReceive.bExecute:=FALSE;
			nServerStep:=ENUM_tcp_server.nWhetherReceive;
		END_IF
	ENUM_tcp_server.nWhetherReceive://判断是否接收成功
		IF SocketReceive.bError THEN
			nServerStep:=ENUM_tcp_server.nCloseAll;
		END_IF
		IF NOT SocketReceive.bBusy AND NOT SocketReceive.bError THEN
			IF nReceiveBytes>0 THEN
				TcpServerStatus.bReceiveDone:=TRUE;
				nServerStep:=ENUM_tcp_server.nDetermineAction;
			ELSE
				nServerStep:=ENUM_tcp_server.nDetermineAction;
			END_IF
		END_IF

	ENUM_tcp_server.nSend://发送接收数据
		SocketSend.bExecute:=TRUE;
		IF SocketSend.bBusy THEN
			SocketSend.bExecute:=FALSE;
			nServerStep:=ENUM_tcp_server.nWhetherSend;
		END_IF
	ENUM_tcp_server.nWhetherSend://判断是否发送成功
		IF SocketSend.bError THEN
			nServerStep:=ENUM_tcp_server.nCloseAll;
		END_IF
		IF NOT SocketSend.bBusy AND NOT SocketSend.bError THEN
			TcpServerStatus.bSendDone:=TRUE;
			nServerStep:=ENUM_tcp_server.nDetermineAction;
		END_IF

	ENUM_tcp_server.nCloseAll://关闭服务器
		SocketCloseAll.bExecute:=TRUE;
		IF SocketCloseAll.bBusy THEN
			SocketCloseAll.bExecute:=FALSE;
			nServerStep:=ENUM_tcp_server.nWhetherCloseAll;
		END_IF
	ENUM_tcp_server.nWhetherCloseAll://判断是否关闭服务器
		IF SocketCloseAll.bError THEN
			nServerStep:=ENUM_tcp_server.nInitial;
		END_IF
		IF NOT SocketCloseAll.bBusy AND NOT SocketCloseAll.bError THEN
			TcpServerStatus.bListenDone:=FALSE;
			TcpServerStatus.bAcceptAccepted:=FALSE;
			TcpServerStatus.bReceiveDone:=FALSE;
			TcpServerStatus.bSendDone:=FALSE;
			TcpServerStatus.bCloseAllDone:=TRUE;
			nServerStep:=ENUM_tcp_server.nInitial;
		END_IF
END_CASE

//功能块
SocketListen(
	sSrvNetId:='' , 
	sLocalHost:=TcpServerParameter.sIp , 
	nLocalPort:=TcpServerParameter.nPort , 
	bExecute:= , 
	tTimeout:=T#10S , 
	bBusy=> , 
	bError=> , 
	nErrId=> , 
	hListener=>hListener );

SocketAccept(
	sSrvNetId:='' , 
	hListener:=hListener , 
	bExecute:= , 
	tTimeout:=T#10S , 
	bAccepted=>TcpServerStatus.bAcceptAccepted , 
	bBusy=> , 
	bError=> , 
	nErrId=> , 
	hSocket=>hSocket );

SocketReceive(
	sSrvNetId:='' , 
	hSocket:=hSocket , 
	cbLen:=TcpServerParameter.nReceiveDataLength , 
	pDest:=ADR(TcpServerParameter.ReceiveData) , 
	bExecute:= , 
	tTimeout:=T#10S , 
	bBusy=> , 
	bError=> , 
	nErrId=> , 
	nRecBytes=>nReceiveBytes );
IF nReceiveBytes>0 THEN
	TcpServerParameter.ReceiveData.sString:=LEFT(TcpServerParameter.ReceiveData.sString,UDINT_TO_INT(nReceiveBytes));
	FOR i:=nReceiveBytes TO 255 BY 1 DO
		TcpServerParameter.ReceiveData.nByte[i]:=0;
	END_FOR
END_IF

IF SocketSend.bExecute THEN
	FOR i:=TcpServerParameter.nSendDataLength TO 255 BY 1 DO
		TcpServerParameter.SendData.nByte[i]:=0;
	END_FOR
END_IF
SocketSend(
	sSrvNetId:='' , 
	hSocket:=hSocket , 
	cbLen:=TcpServerParameter.nSendDataLength , 
	pSrc:=ADR(TcpServerParameter.SendData) , 
	bExecute:= , 
	tTimeout:=T#10S , 
	bBusy=> , 
	bError=> , 
	nErrId=> );

SocketCloseAll(
	sSrvNetId:='' ,
	bExecute:= , 
	tTimeout:=T#10S , 
	bBusy=> , 
	bError=> , 
	nErrId=> );

GVL_tcp

VAR_GLOBAL
	tcpClient:ST_tcp_client;

	tcpServer:ST_tcp_server;
END_VAR

P_tcp_client

//远程IP和端口号
IF tcpClient.parameter.sIp='' THEN
	tcpClient.parameter.sIp:='192.168.0.240';
	tcpClient.parameter.nPort:=55;
END_IF

//功能块
tcpClient.FB(
	TcpClientControl:=tcpClient.control , 
	TcpClientParameter:=tcpClient.parameter , 
	TcpClientStatus=>tcpClient.status );

//复位
IF tcpClient.status.bSendDone THEN
	tcpClient.control.bSend:=FALSE;
END_IF

P_tcp_server

//本地IP和端口号
IF tcpServer.parameter.sIp='' THEN
	tcpServer.parameter.sIp:='192.168.0.240';
	tcpServer.parameter.nPort:=66;
END_IF

//功能块
tcpServer.FB(
	TcpServerControl:=tcpServer.control , 
	TcpServerParameter:=tcpServer.parameter , 
	TcpServerStatus=>tcpServer.status );

//复位
IF tcpServer.status.bSendDone THEN
	tcpServer.control.bSend:=FALSE;
END_IF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值