主程序通过调用SyslibSockets.lib库内部的Sockets函数完成端口绑定,并实施对应端口的监听,当Modbus Tcp客户端请求建立连接时候,服务器端建立连接,并进行数据的交换读写,为了便于判断客户端和服务器端的连接状态,程序做了实时的报文刷新,当通讯建立连接之后,服务器端没有接收到新的报文,且维持一段时间后,则按照通讯中断处理,关闭Sockets,并重新初始化参数,服务器端再次进入监听状态,这种控制模式可以辨识网络物理断线和客户端异常断开这些情况。 address.sin_addr:=SysSockInetAddr(ip); IF terminate=FALSE THEN CASE tcp_state OF 0:
socketId := SysSockCreate(SOCKET_AF_INET,SOCKET_STREAM,0); IF socketId <> SOCKET_INVALID THEN
SysSockSetOption(socketId, SOCKET_SOL, SOCKET_SO_REUSEADDR, ADR(dwValue), SIZEOF (dwValue));
tcp_state := 10; END_IF
10:bResult := SysSockBind(socketId, ADR(address), SIZEOF(address)); IF bResult THEN tcp_state := 20; END_IF …… 50:
SocketHandle := SlaveSocketList.fd_array[TCPindex]; IF SocketHandle = socketId THEN diSize := SIZEOF(Address);
SocketHandle:=SysSockAccept(socketId, ADR(Address), ADR(address)); tcp_state := 100; END_IF 100:
(* SysSockSend(socketId,ADR(send),SIZEOF(send),1);*) SysSockRecv(SocketHandle,ADR(receive1),SIZEOF(receive1),1); ……
IF protocol_id=0 AND device_id>=0 AND receive1[1]<>0 THEN (*modbus_tcp,protocol_id=0*) frame_process(); tcp_state := 120; END_IF; END_CASE; END_IF;
1.3.4 创建MODBUS_TCP SERVER 报文处理程序(部分子程序)
当服务器端 接收到客户端的报文之后,经过了Modbus Tcp 协议ID和功能码有效性判断之后,调用报文处理程序,在报文处理程序中,主要是根据01,02,03,04,05,06,15,16 MODBU-TCP读写字,读写位功能码分别进行处理。例如进行写寄存器功能的处理时,先判断写入寄存器的起始地址和写入寄存器个数,再进行带地址偏移的赋值,在赋值过程中要进行高低字节的转换,以保证数据的正确性。 Frame_process (*MODBUS_TCP报文处理*) IF (send_do =FALSE )THEN
CASE input_byte1[2] OF
03:(*读寄存器*) ……
address_temp:=SHL(BYTE_TO_INT(input_byte1[3]),8) + ( BYTE_TO_INT(input_byte1[4])); ……
FOR move_to_send:=address_temp TO address_temp+(length_temp)*2 DO
output_byte[4+move_to_send-address_temp]:=mw_area[move_to_send+address_temp+1]; END_FOR; …… END_CASE; END_IF;
2 .MODBUS_TCP server 的验证使用
在MODBUS_TCP sever通讯程序完成之后,通过wireshark以太网抓包软件分析MODBUS-TCP报文,并使用Easybuilder800触摸屏软件实现了触摸屏和PAC控制器的MODBUS_TCP通讯。
图4. wireshark以太网抓包软件分析的MODBUS-TCP报文
相关推荐: