QT TCP客户端发送数据异常:netcat接收随机值问题求助
QT TCP控制台客户端发送数据异常问题
用QT实现简单TCP控制台客户端时遇到问题:客户端实例化Socket连接本地监听的netcat服务器后,发送的数据与netcat接收的数据不匹配,且每次运行结果非确定(每次数据都不同)。
相关代码片段
#include <QCoreApplication> #include <QDebug> #include <QByteArray> #include <QTcpSocket> enum class Command: unsigned char { getNodeConnectionStatus = 0x00, getNodeHopCount, getNodesParent = 0x10 }; struct CommandHeader { Command command; size_t size; } __attribute__((packed,aligned(1))); struct Address { unsigned char value[24]; } __attribute__((packed,aligned(1))); struct CommandPayload { struct Address address; }; struct NodeHopCount: public CommandPayload { }; struct CommandPacket { struct CommandHeader header; unsigned char *payload; }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QTcpSocket socket; socket.connectToHost("localhost", 2500); CommandPacket p; p.header.command = Command::getNodeHopCount; p.header.size = 1; struct NodeHopCount payload; memset(payload.address.value, '\0', 24); memcpy(payload.address.value, "AA:BB:CC:DD:EE:FF:00:11", 23); p.payload = new unsigned char[sizeof(payload)]; memset(p.payload, '\0', sizeof(payload)); memcpy(reinterpret_cast<void *>(p.payload), reinterpret_cast<void *>(&payload), sizeof(payload)); QByteArray bytes(reinterpret_cast<char *>(&p), sizeof(p.header) + sizeof(payload)); socket.write(bytes); socket.flush(); socket.close(); return a.exec(); }
两次连续运行的netcat输出
solux [bin]$ nc -l -p 2500 -x -vv Listening on any address 2500 (rtsserv) Connection from 127.0.0.1:36670 ▒����l��]U Received 33 bytes from the socket 00000000 01 01 00 00 00 00 00 00 00 1A 81 86 C8 7F 00 00 ................ 00000010 C0 6C ED 92 5D 55 00 00 01 00 00 00 00 00 00 00 .l..]U.......... 00000020 20 Total received bytes: 33 Total sent bytes: 0 solux [bin]$ nc -l -p 2500 -x -vv Listening on any address 2500 (rtsserv) Connection from 127.0.0.1:50468 ▒a%�bp�U Received 33 bytes from the socket 00000000 01 01 00 00 00 00 00 00 00 1A 61 00 25 7F 00 00 ..........a.%... 00000010 C0 1C 62 70 AF 55 00 00 01 00 00 00 00 00 00 00 ..bp.U.......... 00000020 20 Total received bytes: 33 Total sent bytes: 0
问题分析与修复
根本问题
CommandPacket结构体误用:payload是指针类型,存储的是堆内存地址而非实际数据。你直接取&p构造QByteArray,发送的是指针本身的随机地址值,而非payload指向的真实数据,这就是每次结果不确定的原因。header.size值错误:设置为1,但实际NodeHopCount的大小是24字节,与真实payload长度不符。- 异步连接未等待:
connectToHost是异步操作,未等待连接成功就发送数据,可能导致数据发送不完整或失败。
修复方案
- 直接拼接
header和payload的实际数据,而非发送指针。 - 修正
header.size为真实payload长度。 - 通过信号槽等待连接成功后再发送数据,确保发送时机正确。
修改后的代码示例
#include <QCoreApplication> #include <QDebug> #include <QByteArray> #include <QTcpSocket> #include <QTimer> enum class Command: unsigned char { getNodeConnectionStatus = 0x00, getNodeHopCount, getNodesParent = 0x10 }; struct CommandHeader { Command command; size_t size; } __attribute__((packed,aligned(1))); struct Address { unsigned char value[24]; } __attribute__((packed,aligned(1))); struct NodeHopCount { Address address; } __attribute__((packed,aligned(1))); int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QTcpSocket socket; // 连接成功后发送数据 QObject::connect(&socket, &QTcpSocket::connected, [&](){ CommandHeader header; header.command = Command::getNodeHopCount; header.size = sizeof(NodeHopCount); // 修正为真实payload长度 NodeHopCount payload; memset(payload.address.value, '\0', 24); memcpy(payload.address.value, "AA:BB:CC:DD:EE:FF:00:11", 23); // 拼接header和payload到连续字节数组 QByteArray bytes; bytes.append(reinterpret_cast<const char*>(&header), sizeof(header)); bytes.append(reinterpret_cast<const char*>(&payload), sizeof(payload)); qint64 sent = socket.write(bytes); qDebug() << "已发送" << sent << "字节"; socket.flush(); socket.close(); // 发送完成后退出事件循环 QTimer::singleShot(100, &a, &QCoreApplication::quit); }); // 处理连接错误 QObject::connect(&socket, &QTcpSocket::errorOccurred, [&](QAbstractSocket::SocketError err){ qDebug() << "Socket错误:" << err; a.quit(); }); socket.connectToHost("localhost", 2500); return a.exec(); }
内容的提问来源于stack exchange,提问作者Ulisse Rubizzo
相关产品推荐
相关产品推荐

