连接 ZH‑T08R
发送:00 00 00 00 00 06 01 03 00 00 00 02
定时器 200ms 自动循环读取
实时显示:原始报文 + 第一通道电阻(十进制 Ω)
需要添加 ws2_32.lib 库

界面控件 ID 清单(必须对应)
IP 编辑框:IDC_EDIT_IP
端口编辑框:IDC_EDIT_PORT
开始按钮:IDC_BTN_READ(标题:开始实时读取)
停止按钮:IDC_BTN_STOP(标题:停止)
电阻显示:IDC_EDIT_RESIST
原始接收框:IDC_EDIT_RECV

ModbusTCPDlg.h
cpp
#if !defined(AFX_MODBUSTCPDLG_H__12345678_ABCD_1234_5678_000000000001__INCLUDED_)
#define AFX_MODBUSTCPDLG_H__12345678_ABCD_1234_5678_000000000001__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
#include <winsock2.h>
class CModbusTCPDlg : public CDialog
{
public:
CModbusTCPDlg(CWnd* pParent = NULL);
enum { IDD = IDD_MODBUSTCP_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
protected:
HICON m_hIcon;
SOCKET m_sock;
BOOL m_bConnected;
UINT m_nTimerID;
BOOL ConnectServer(CString ip, int port);
void ReadModbusData();
void CloseSocket();
void StartTimer();
void StopTimer();
//{{AFX_MSG(CModbusTCPDlg) // 类向导必须的消息开始标记
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnBtnRead();
afx_msg void OnBtnStop();
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnCancel();
//}}AFX_MSG // 类向导必须的消息结束标记
DECLARE_MESSAGE_MAP()
};
#endif
ModbusTCPDlg.cpp
cpp
#include "stdafx.h"
#include "ModbusTCP.h"
#include "ModbusTCPDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BEGIN_MESSAGE_MAP(CModbusTCPDlg, CDialog)
//{{AFX_MSG_MAP(CModbusTCPDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_BN_CLICKED(IDC_BTN_READ, OnBtnRead)
ON_BN_CLICKED(IDC_BTN_STOP, OnBtnStop)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CModbusTCPDlg::CModbusTCPDlg(CWnd* pParent /*=NULL*/)
: CDialog(CModbusTCPDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_sock = INVALID_SOCKET;
m_bConnected = FALSE;
m_nTimerID = 0;
}
void CModbusTCPDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BOOL CModbusTCPDlg::OnInitDialog()
{
CDialog::OnInitDialog();
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
SetDlgItemText(IDC_EDIT_IP, "192.168.0.7");
SetDlgItemText(IDC_EDIT_PORT, "20108");
return TRUE;
}
void CModbusTCPDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0);
int cx = GetSystemMetrics(SM_CXICON);
int cy = GetSystemMetrics(SM_CYICON);
CRect rc; GetClientRect(&rc);
int x = (rc.Width()-cx)/2;
int y = (rc.Height()-cy)/2;
dc.DrawIcon(x,y,m_hIcon);
}
else
CDialog::OnPaint();
}
HCURSOR CModbusTCPDlg::OnQueryDragIcon()
{
return (HCURSOR)m_hIcon;
}
BOOL CModbusTCPDlg::ConnectServer(CString ip, int port)
{
m_sock = socket(AF_INET,SOCK_STREAM,0);
if(m_sock == INVALID_SOCKET) return FALSE;
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.S_un.S_addr = inet_addr(ip);
if(connect(m_sock,(sockaddr*)&addr,sizeof(addr)) == SOCKET_ERROR)
{
closesocket(m_sock);
m_sock = INVALID_SOCKET;
return FALSE;
}
return TRUE;
}
void CModbusTCPDlg::CloseSocket()
{
if(m_sock != INVALID_SOCKET)
{
closesocket(m_sock);
m_sock = INVALID_SOCKET;
}
m_bConnected = FALSE;
}
void CModbusTCPDlg::StartTimer()
{
if(m_nTimerID == 0)
m_nTimerID = SetTimer(1001,200,NULL);
}
void CModbusTCPDlg::StopTimer()
{
if(m_nTimerID != 0)
{
KillTimer(m_nTimerID);
m_nTimerID = 0;
}
}
void CModbusTCPDlg::OnTimer(UINT nIDEvent)
{
if(nIDEvent == 1001)
ReadModbusData();
CDialog::OnTimer(nIDEvent);
}
// ===================== 核心发送与解析 =====================
void CModbusTCPDlg::ReadModbusData()
{
if(!m_bConnected || m_sock == INVALID_SOCKET) return;
BYTE sendBuf[12] = {
0x00,0x00,
0x00,0x00,
0x00,0x06,
0x01,
0x03,
0x00,0x00,
0x00,0x02
};
send(m_sock,(char*)sendBuf,12,0);
BYTE recvBuf[1024] = {0};
int len = recv(m_sock,(char*)recvBuf,1024,0);
if(len <= 0) return;
CString strRecv;
for(int i=0;i<len;i++){
CString t; t.Format("%02X ",recvBuf[i]);
strRecv += t;
}
SetDlgItemText(IDC_EDIT_RECV,strRecv);
// 解析 32 位电阻(0.01Ω)
if(len >= 13)
{
DWORD h16 = (recvBuf[9]<<8) | recvBuf[10];
DWORD l16 = (recvBuf[11]<<8) | recvBuf[12];
DWORD val = (h16<<16) | l16;
float r = val / 100.0f;
CString strR;
strR.Format("%.2f Ω",r);
SetDlgItemText(IDC_EDIT_RESIST,strR);
}
}
void CModbusTCPDlg::OnBtnRead()
{
CString ip,portStr;
GetDlgItemText(IDC_EDIT_IP,ip);
GetDlgItemText(IDC_EDIT_PORT,portStr);
int port = atoi(portStr);
StopTimer();
CloseSocket();
if(ConnectServer(ip,port))
{
m_bConnected = TRUE;
StartTimer();
MessageBox("连接成功,开始实时采集","提示");
}
else
MessageBox("连接失败!检查IP/网络/模块","错误");
}
void CModbusTCPDlg::OnBtnStop()
{
StopTimer();
CloseSocket();
MessageBox("已停止读取","提示");
}
void CModbusTCPDlg::OnCancel()
{
StopTimer();
CloseSocket();
WSACleanup();
CDialog::OnCancel();
}
运行程序
