Modbus编程实践

一、wireshark抓包

1. 运行crazychat.exe

用本机和虚拟机分别打开运行程序,并且输入相同的房间号。
在这里插入图片描述

2. 发送和接收消息

在这里插入图片描述
在这里插入图片描述

3. 抓包

在wireshake中及时找到,可以看到 Ip address为广播地址39.156.132.43

在这里插入图片描述
双击打开,可以看到端口号和发送的信息明文显示及字节编码。
在这里插入图片描述

4. 小结

(1)由筛选出来的抓包文件可以看出,软件使用的协议是UDP。
(2)抓取包中找到窃取到的聊天信息 (英文字符和汉字可能经过了某种编码转换,数据包中不是明文)。用的是16进制的字符,如果要每一个都看懂,一定要对编码方式非常了解。例如:前4个字节代表什么,紧接着xx个字节代表什么之类的。
(3)能在多台电脑上同时传输聊天数据的原因是发送信息时使用的广播地址,所以可以多方收到消息。

二、C编程modbus协议

1. Modbus协议简单介绍

(1)Modbus简单概述
Modbus协议是一种串行通信协议,是Modicon公司(现在的施耐德电气Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表的。Modbus协议是应用层协议,已经成为工业领域通信协议的业界标准,是工业电子设备之间常用的连接方式。

Modbus是一个master/slave架构的协议,有一个节点是master节点,其他使用Modbus协议参与通信的节点是slave节点,每一个slave设备都有一个唯一的地址。只有被指定为master节点的节点可以启动一个命令。所有的Modbus数据帧包含了校验码,保证传输的正确性。基本的ModBus命令能指令一个slave设备改变它的寄存器的某个值,控制或者读取一个I/O端口,以及指挥设备回送一个或者多个其寄存器中的数据。

(2)Modbus主/从协议原理
Modbus串行链路协议是一个主-从协议。在同一时间,只能将一个主站连接到总线,将一个或多个从站(最大数量为247)连接到相同的串行总线。Modbus 通讯总是由主站发起,当从站没有收到来自主站的请求时,将不会发送数据。主站同时只能启动一个Modbus事务处理,从站之间不能相互通信。

(3)Modbus协议数据单元
Modbus协议定义了一个与基础通信层无关的简单协议数据单元(PDU),特定总线或网络上的Modbus协议映射能够在应用数据单元(ADU)上引入一些附加域。

在这里插入图片描述

(4)Modbus串行传输协议
RTU模式:每个8 Bit字节包含两个4 Bit的十六进制字符,其优点是在同样的波特率下,可比ASCII方式传送更多的数据,但是每个信息必须以连续的数据流传输。(等下我们要使用的传输协议)
在这里插入图片描述

ASCII模式:信息中的每个8 Bit字节需2个ASCII字符,其优点是准许字符的传输间隔达到1s 而不产生错误;
在这里插入图片描述

(5)ModbusTCP通信结构
Modbus TCP/IP的通信设备:连接至TCP/IP网络的
Modbus TCP/IP客户机和服务器设备。
互连设备,如:在TCP/IP网络和串行链路子网之间互连的网桥、路由器或网关等设备。
在这里插入图片描述

2. c语言完成modbus协议从云端服务器读取信息
(1)TCP方式请求数据

新建一个TCP客户端项目
在这里插入图片描述
初始化socket dll,通过IP连接服务器对应端口

// 初始化socket dll。
	WORD winsock_version = MAKEWORD(2,2);
	WSADATA wsa_data;
	if (WSAStartup(winsock_version, &wsa_data) != 0) {
		printf("Failed to init socket!\n");
		return 1;
	}
	
	SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (client_socket == INVALID_SOCKET) {
		printf("Failed to create server socket!\n");
		return 2;
	}
	
	struct sockaddr_in server_addr;
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(PORT);
	server_addr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
	if (connect(client_socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
		printf("Failed to connect server: %ld !\n", GetLastError());
		return 3;
	}

输入指令格式

	uint8_t data[length_8];
	printf("具体指令给格式为0+传感器编号(1,2,3,4,5)0300010002");
	printf("请输入采集传感器的指令):\r\n");
	scanf("%s",data);

生成将输入指令转化为hex格式并生成crc16校验码

uint16_t crc;
		unsigned char * cmd;
		char crc1[8];
	    cmd = fromhex(data);
		crc = CRC_16(cmd);
		uint8_t a = 0xFF;
		for(int i=0;i<6;i++){
			//TODO
			crc1[i] = cmd[i];
		}
		crc1[6] = a & crc;
		crc1[7] = (crc >> 8) & a;

三、总结

通过本次实验主要是了解和使用Modbus通讯协议进行各种传感器之间的串行通讯。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值