ModbusTCP协议通信 C++实现源码举例

因项目需求研究了一下Modbus协议,用C++实现了简单的Modbus协议报文组织
Modbus协议允许在TCP连接下实现通信,使用ws2_32这个socket支持库,写法是普遍的网络编程TCP客户端连接写法

在Windows环境下,C++的TCP连接发起部分代码:作为主机(客户端),主动连接从机(服务端)

	WORD version = MAKEWORD(2, 2);
	WSADATA data;
	if (SOCKET_ERROR == WSAStartup(version, &data))
	{
		_csock = INVALID_SOCKET;
		qDebug("初始化Winsock环境失败");
		return false;
	}
	_csock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (_csock == INVALID_SOCKET) {
		return false;
	}
	sockaddr_in _csin = {};
	_csin.sin_family = AF_INET;
	_csin.sin_port = htons(SLAVE_PORT);
	_csin.sin_addr.S_un.S_addr = inet_addr(SLAVE_ADDRESS);
	if (SOCKET_ERROR == connect(_csock, reinterpret_cast<sockaddr*>(&_csin), sizeof(_csin)))
	{
		_csock = INVALID_SOCKET;
		qDebug("connect error");
		return false;
	}
	return true;

TCP连接完成后,发送的数据包格式,即为ModbusTCP的协议格式,以下是协议完整格式:

Modbus协议头
事务处理标识 协议标识 长度 单元标识符
2字节 2字节 2字节 1字节

接下来就是Modbus协议主体
功能码 数据

所以举个例子:

//组织二进制Modbus协议报文
	unsigned char sendBuf[21];//发送缓存
	short temps = _seq_modbus++;//类似于TCP的seq序列号,让其自增即可
	unsigned char* temp = reinterpret_cast<unsigned char*>(&temps);
	//协议头
	sendBuf[0] = *(temp+1);//前两位为事务处理标识,2个字节的序列号
	sendBuf[1] = *(temp);
	
	sendBuf[2] = 0;//协议标识,两个字节,0000即为Modbus TCP协议
	sendBuf[3] = 0;
	
	sendBuf[4] = 0;//长度字段(前半部分字节)
	sendBuf[5] = 15;//随后字节数
	
	sendBuf[6] = 0x01;//单元标志,定义连接目的节点的其他设备(这个设备是1号,所以是0x01)
	//以上是Modbus协议头部分
	//协议体
	sendBuf[7] = 0x10;//Modbus功能码 ,这里是 写多个保持寄存器 操作
	
	sendBuf[8] = 0x01; //写寄存器起始地址高字节
	sendBuf[9] = 0x00; //写寄存器起始地址低字节(所以这里是往0x0100地址写寄存器)

	sendBuf[10] = 0x00; //写寄存器数量高字节
	sendBuf[11] = 0x04; //写寄存器数量低字节
	
	sendBuf[12] = 0x08; //数据长度
	
	//写四个值到报文中
	temps = _offset.x;
	sendBuf[13] = *(temp+1);
	sendBuf[14] = *(temp);

	temps = _offset.y;
	sendBuf[15] = *(temp+1);
	sendBuf[16] = *(temp);


	temps = _offset.x + 50;
	sendBuf[17] = *(temp+1);
	sendBuf[18] = *(temp);

	temps = 50 - _offset.y;
	sendBuf[19] = *(temp+1);
	sendBuf[20] = *(temp);
	// ----------------
	//最后发送出去
	send(_csock, reinterpret_cast<char*>(sendBuf), sizeof(sendBuf), 0);//发送报文

大家看懂这个例子了吗,其实这个例子就是“使用ModbusTCP协议写4个字节的数据到0x0100 - 0x0103这四个寄存器中”
其实Modbus协议本身功能很多,这里只举例了一个写“多个寄存器”的操作,其实还有其他操作,具体的协议格式可以去官网或者其他地方查询。

记之备忘,希望有帮助到需要的同学

上一篇:Modsim32与Modscan32 仿真测试ModbusTCP


下一篇:IoTClient开发3 - ModBusTcp协议客户端实现