c++ - 通过 Modbus TCP 向设备发送第二个命令代码的问题
问题描述
我是初学者,无法通过 Modbus TCP 发送消息。我在端口 502 上创建带有 RFID 读/写头的 win 套接字,然后我将第一个命令 10h (write_multiple_registers) 发送到头,我收到回复没有问题...之后我认为准备好发送下一个命令(再次 10h 或 03h (read_holding_registers) 但它不起作用。我必须创建一个新的套接字,然后它才能工作,直到执行第一个命令......似乎 RFID 头没有收到命令。我通常使用 send() 和 recv()功能。我尝试通过像 SimplyModbus 这样的测试仪测试设备,一切正常,没有问题。有人有这个问题的经验吗?非常感谢您的帮助!
#ifndef PCH_H
#define PCH_H
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <Winsock2.h>
#include <WS2tcpip.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include <conio.h>
#pragma comment (lib,"WS2_32.lib")
using namespace std;
using std::string;
typedef SSIZE_T ssize_t;
#endif //PCH_H
bool modbus::modbus_connect() {
if(HOST == "" || PORT == 0) {
std::cout << "Missing Host and Port" << std::endl;
return false;
} else {
std::cout << "Found Proper Host "<< HOST << " and Port " <<PORT <<std::endl;
}
WSAData data;
sockaddr_in _server;
WORD ver = MAKEWORD(2, 2);
wsResult = WSAStartup(ver, &data);
if (wsResult != 0)
{
cerr << "Error Create Socket" << wsResult << endl;
return false;
}
_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(_socket == -1) {
std::cout <<"Error Opening Socket" <<std::endl;
return false;
} else {
std::cout <<"Socket Opened Successfully" << std::endl;
}
u_long iMode = 0;
wsResult = ioctlsocket(_socket, FIONBIO, &iMode);
_server.sin_family = AF_INET;
_server.sin_addr.s_addr = inet_addr(HOST.c_str());
_server.sin_port = htons(PORT);
wsResult = ::bind(_socket,(sockaddr*)&_server, sizeof(_server));
if (connect(_socket, (sockaddr*)&_server, sizeof(_server)) < 0) {
std::cout<< "Connection Error" << std::endl;
return false;
}
std::cout<< "Connected" <<std::endl;
_connected = true;
return true;
}
ssize_t modbus::modbus_send(uint8_t *to_send, int length)
{
FD_ZERO(&fds);
tv.tv_sec = 5;
tv.tv_usec = 0;
FD_SET(_socket, &fds);
int i = select(32, NULL, &fds, NULL, &tv); // write
if (i <= 0)
{
printf("select - error %d\n", WSAGetLastError());
closesocket(_socket);
WSACleanup();
return 1;
}
_msg_id++;
wsResult = send(_socket, (const char*)to_send, (size_t)length, 0);
if (wsResult == SOCKET_ERROR)
{
printf("send failed with error: %d\n", WSAGetLastError());
WSACleanup();
}
return 0;
}
ssize_t modbus::modbus_receive(uint8_t *buffer)
{
FD_ZERO(&fds);
tv.tv_sec = 5;
tv.tv_usec = 0;
FD_SET(_socket, &fds);
int i = select(32, &fds, NULL, NULL, &tv); //read
if (i <= 0)
{
printf("no TCP response received\n");
closesocket(_socket);
WSACleanup();
return 1;
}
wsResult = recv(_socket, (char *)buffer, 1024, 0);
if (wsResult == 0)
{
printf("received failed with error: %d\n", WSAGetLastError());
WSACleanup();
}
return 0;
}
解决方案
推荐阅读
- python - Pyspark中RDD到DF的不完全转换
- sql-server - 在 SQL Server 中查询“每次支付相应账单后的余额”
- node.js - 在循环中将数据添加到 Cloud Firestore
- sql - SSRS - 针对某一列的值数
- javascript - Ag-Grid - 服务器端行模型 params.failCallback
- arrays - DO 循环更新分配 SAS
- node.js - MongoDB 按字段 valeu 查询子文档
- ruby - Watir:检索与属性匹配的所有动态 HTML 元素?
- c# - 如何从 IActionResult 检索 HTTP 代码和内容?
- python - 如何仅打印非 NaN 值?