一、下载网络调试助手
下载连接:通过网盘分享的文件:网络调试助手.exe
链接: https://pan.baidu.com/s/1A-aQ9oLb3aGdxDT8bl6qjw?pwd=nf1z 提取码: nf1z
就一个.exe,点两次打开两个,两个配置:
设置一个调试助手为 TCP 服务器
- 打开第一个网络调试助手,选择 TCP Server 模式。
- 配置服务器参数 :
- 本地 IP 地址 :选择本机 IP(通常为
127.0.0.1
用于本地测试,或局域网 IP 如192.168.x.x
)。 - 监听端口 :设置一个端口号(如
8888
),确保该端口未被其他程序占用。 - 启动服务器:点击"启动"或"监听"按钮,调试助手进入监听状态,等待客户端连接。
- 本地 IP 地址 :选择本机 IP(通常为
- 记录服务器信息:记下服务器的 IP 地址和端口号,用于客户端配置。
设置另一个调试助手为 TCP 客户端
- 打开第二个网络调试助手,选择 TCP Client 模式。
- 配置客户端参数 :
- 远程主机 IP :输入服务器的 IP 地址(与服务器端一致,如
127.0.0.1:8888
或局域网 IP)。 - 远程端口 :输入服务器监听的端口号(如
8888
)。 - 连接服务器:点击"连接"按钮,客户端会尝试连接到服务器。
- 远程主机 IP :输入服务器的 IP 地址(与服务器端一致,如
- 确认连接状态:连接成功后,服务器端会显示客户端已连接。

然后互相发个什么能接收就行
二、PyQt实现
再用PyQt实现并验证功能,充当TCP Client

PyQt代码如下:
python
import sys
import socket
import threading
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QTextEdit, QCheckBox
from PyQt5.QtCore import pyqtSignal, QObject
class Communicate(QObject):
# 自定义信号,用于线程和主界面通信
data_received = pyqtSignal(str)
status_updated = pyqtSignal(str)
class TCPClientWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PyQt TCP Client")
self.resize(600, 400)
# 初始化通信对象
self.comm = Communicate()
self.comm.data_received.connect(self.update_display)
self.comm.status_updated.connect(self.update_status)
# 初始化 socket
self.client_socket = None
self.running = False
# 创建界面
self.init_ui()
def init_ui(self):
# 主布局
main_widget = QWidget()
self.setCentralWidget(main_widget)
layout = QVBoxLayout(main_widget)
# IP 和端口输入
ip_port_layout = QHBoxLayout()
self.ip_input = QLineEdit("127.0.0.1")
self.port_input = QLineEdit("8888")
ip_port_layout.addWidget(QLineEdit("IP:"))
ip_port_layout.addWidget(self.ip_input)
ip_port_layout.addWidget(QLineEdit("Port:"))
ip_port_layout.addWidget(self.port_input)
layout.addLayout(ip_port_layout)
# 连接、断开、清空按钮
button_layout = QHBoxLayout()
self.connect_btn = QPushButton("Connect")
self.disconnect_btn = QPushButton("Disconnect")
self.clear_btn = QPushButton("Clear Log")
self.connect_btn.clicked.connect(self.connect_to_server)
self.disconnect_btn.clicked.connect(self.disconnect)
self.clear_btn.clicked.connect(self.clear_log)
self.disconnect_btn.setEnabled(False)
button_layout.addWidget(self.connect_btn)
button_layout.addWidget(self.disconnect_btn)
button_layout.addWidget(self.clear_btn)
layout.addLayout(button_layout)
# 接收数据区域
self.display = QTextEdit()
self.display.setReadOnly(True)
layout.addWidget(self.display)
# 发送数据区域
send_layout = QHBoxLayout()
self.send_input = QLineEdit()
self.send_btn = QPushButton("Send")
self.hex_check = QCheckBox("Hex Mode")
self.send_btn.clicked.connect(self.send_data)
send_layout.addWidget(self.send_input)
send_layout.addWidget(self.send_btn)
send_layout.addWidget(self.hex_check)
layout.addLayout(send_layout)
def connect_to_server(self):
ip = self.ip_input.text()
try:
port = int(self.port_input.text())
except ValueError:
self.comm.status_updated.emit("Invalid port number!")
return
try:
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.client_socket.connect((ip, port))
self.running = True
self.comm.status_updated.emit(f"Connected to {ip}:{port}")
self.connect_btn.setEnabled(False)
self.disconnect_btn.setEnabled(True)
# 启动接收线程
threading.Thread(target=self.receive_data, daemon=True).start()
except Exception as e:
self.comm.status_updated.emit(f"Connection failed: {str(e)}")
def disconnect(self):
self.running = False
if self.client_socket:
self.client_socket.close()
self.client_socket = None
self.comm.status_updated.emit("Disconnected")
self.connect_btn.setEnabled(True)
self.disconnect_btn.setEnabled(False)
def receive_data(self):
while self.running:
try:
data = self.client_socket.recv(1024)
if not data:
self.comm.status_updated.emit("Server closed connection")
self.disconnect()
break
if self.hex_check.isChecked():
# 十六进制显示
data_str = data.hex()
else:
# 文本显示(假设 UTF-8 编码)
data_str = data.decode('utf-8', errors='ignore')
self.comm.data_received.emit(data_str)
except Exception as e:
if self.running:
self.comm.status_updated.emit(f"Receive error: {str(e)}")
self.disconnect()
break
def send_data(self):
if not self.client_socket or not self.running:
self.comm.status_updated.emit("Not connected to server!")
return
data = self.send_input.text()
try:
if self.hex_check.isChecked():
# 发送十六进制数据
data_bytes = bytes.fromhex(data)
else:
# 发送文本数据
data_bytes = data.encode('utf-8')
self.client_socket.send(data_bytes)
self.comm.data_received.emit(f"Sent: {data}")
except Exception as e:
self.comm.status_updated.emit(f"Send error: {str(e)}")
def update_display(self, data):
self.display.append(data)
def update_status(self, status):
self.display.append(f"[Status] {status}")
def clear_log(self):
self.display.clear()
def closeEvent(self, event):
self.disconnect()
event.accept()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = TCPClientWindow()
window.show()
sys.exit(app.exec_())
三、C++实现(进入正题)
因为毕竟是学习C++,下面就一步步的实现,实现网络调试助手与C++版的QT上位机通讯。
main.cpp代码如下:
cpp
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
dialog.cpp如下:
cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QMessageBox>
#include <QDebug>
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
, tcpSocket(nullptr)
{
ui->setupUi(this);
initUI();
initSocket();
}
Dialog::~Dialog()
{
if(tcpSocket) {
tcpSocket->disconnectFromHost();
delete tcpSocket;
}
delete ui;
}
void Dialog::initUI()
{
// 设置界面默认状态
ui->connectBtn->setText("连接");
ui->sendBtn->setEnabled(false);
ui->ipEdit->setText("127.0.0.1");
ui->portEdit->setText("8080");
ui->receiveText->setReadOnly(true);
}
void Dialog::initSocket()
{
tcpSocket = new QTcpSocket(this);
// 连接信号槽
connect(tcpSocket, &QTcpSocket::connected,
this, &Dialog::on_socket_connected);
connect(tcpSocket, &QTcpSocket::disconnected,
this, &Dialog::on_socket_disconnected);
connect(tcpSocket, &QTcpSocket::readyRead,
this, &Dialog::on_socket_readyRead);
// 修改为使用 errorOccurred 信号
connect(tcpSocket, &QTcpSocket::errorOccurred,
this, &Dialog::on_socket_error);
}
void Dialog::on_connectBtn_clicked()
{
if(!tcpSocket->isOpen()) {
// 连接服务器
QString ip = ui->ipEdit->text();
quint16 port = ui->portEdit->text().toUInt();
tcpSocket->connectToHost(QHostAddress(ip), port);
ui->connectBtn->setText("连接中...");
ui->connectBtn->setEnabled(false);
} else {
// 断开连接
tcpSocket->disconnectFromHost();
ui->connectBtn->setText("断开中...");
}
}
void Dialog::on_sendBtn_clicked()
{
if(tcpSocket && tcpSocket->state() == QAbstractSocket::ConnectedState) {
QString message = ui->sendText->toPlainText();
if(!message.isEmpty()) {
tcpSocket->write(message.toUtf8());
tcpSocket->flush(); // 立即发送
// 添加到发送记录
ui->receiveText->append("[发送] " + message);
ui->sendText->clear();
}
} else {
QMessageBox::warning(this, "警告", "请先连接服务器!");
}
}
void Dialog::on_socket_connected()
{
ui->connectBtn->setText("断开");
ui->connectBtn->setEnabled(true);
ui->sendBtn->setEnabled(true);
ui->statusLabel->setText("状态: 已连接");
ui->receiveText->append("[系统] 连接成功!");
qDebug() << "TCP连接成功";
}
void Dialog::on_socket_disconnected()
{
ui->connectBtn->setText("连接");
ui->connectBtn->setEnabled(true);
ui->sendBtn->setEnabled(false);
ui->statusLabel->setText("状态: 已断开");
ui->receiveText->append("[系统] 连接已断开");
qDebug() << "TCP连接断开";
}
void Dialog::on_socket_readyRead()
{
QByteArray data = tcpSocket->readAll();
QString message = QString::fromUtf8(data);
ui->receiveText->append("[接收] " + message);
qDebug() << "接收数据:" << message;
}
void Dialog::on_socket_error(QAbstractSocket::SocketError socketError)
{
QString errorStr;
switch(socketError) {
case QAbstractSocket::RemoteHostClosedError:
errorStr = "服务器关闭连接";
break;
case QAbstractSocket::HostNotFoundError:
errorStr = "服务器地址错误";
break;
case QAbstractSocket::ConnectionRefusedError:
errorStr = "连接被拒绝";
break;
default:
errorStr = tcpSocket->errorString();
}
ui->connectBtn->setText("连接");
ui->connectBtn->setEnabled(true);
ui->sendBtn->setEnabled(false);
ui->statusLabel->setText("状态: 连接失败");
ui->receiveText->append("[错误] " + errorStr);
QMessageBox::critical(this, "连接错误", errorStr);
qDebug() << "TCP错误:" << errorStr;
}
dialog.h代码如下:
cpp
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QTcpSocket>
#include <QHostAddress>
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
private slots:
void on_connectBtn_clicked();
void on_sendBtn_clicked();
void on_socket_connected();
void on_socket_disconnected();
void on_socket_readyRead();
void on_socket_error(QAbstractSocket::SocketError socketError);
private:
Ui::Dialog *ui;
QTcpSocket *tcpSocket;
void initUI(); // 初始化界面
void initSocket(); // 初始化Socket
};
#endif // DIALOG_H
CMakeLists.txt代码如下:
cpp
cmake_minimum_required(VERSION 3.16)
project(TCP_IP_Test VERSION 0.1 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 添加Network组件到find_package中
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Network LinguistTools)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Network LinguistTools)
set(TS_FILES TCP_IP_Test_zh_CN.ts)
set(PROJECT_SOURCES
main.cpp
dialog.cpp
dialog.h
dialog.ui
${TS_FILES}
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(TCP_IP_Test
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
else()
if(ANDROID)
add_library(TCP_IP_Test SHARED
${PROJECT_SOURCES}
)
else()
add_executable(TCP_IP_Test
${PROJECT_SOURCES}
)
endif()
qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
endif()
# 添加Network到target_link_libraries
target_link_libraries(TCP_IP_Test PRIVATE
Qt${QT_VERSION_MAJOR}::Widgets
Qt${QT_VERSION_MAJOR}::Network # 添加这一行
)
if(${QT_VERSION} VERSION_LESS 6.1.0)
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.TCP_IP_Test)
endif()
set_target_properties(TCP_IP_Test PROPERTIES
${BUNDLE_ID_OPTION}
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)
include(GNUInstallDirs)
install(TARGETS TCP_IP_Test
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(TCP_IP_Test)
endif()
在dialog.ui中要添加如下控件:
控件类型 | 对象名称 | 文本/提示 |
---|---|---|
Line Edit | ipEdit | 127.0.0.1 |
Line Edit | portEdit | 8080 |
QPushButton | connectBtn | 连接 |
Text Edit | sendText | 发送消息... |
QPushButton | sendBtn | 发送 |
Text Edit | receiveText | (只读) |
Label | statusLabel | 状态: 未连接 |

运行结果如下:
