QTcpSocket - 如何发送两个数字
QTcpSocket - How to send two numbers
客户端应用程序通过QTcpSocket向服务器发送两个(ushort)号码:
ushort MessageId = 4;
ushort MessageSize = 0;
socket->write((const char*) &MessageId, sizeof(ushort));
socket->write((const char*) &MessageSize, sizeof(ushort));
socket->waitForBytesWritten();
Server 应用程序接收 4 字节长的消息并将其放入 QByteArray 缓冲区然后解码数字:
int bytes = socket->bytesAvailable();
QByteArray buffer = socket->read(bytes)
const char * messageIdBytes = buffer.mid(0, 2);
ushort messageId = (ushort)(*messageIdBytes);
const char * messageSizeBytes = buffer.mid(2, 4);
ushort messageSize = (ushort)(*messageSizeBytes );
qDebug() << QString("MessageId Bits: [%1], Value: [%2].").arg(QString::number(messageId, 2), QString::number(messageId));
qDebug() << QString("MessageSize Bits: [%1], Value: [%2].").arg(QString::number(messageSize, 2), QString::number(messageSize));
这给出了以下服务器输出:(为了便于阅读,我添加了空格)
MessageId Bits: [1111 1111 1101 1101], Value: [65501].
MessageSize Bits: [1111 1111 1101 1101], Value: [65501].
- 问题:服务器输出应该收到 MessageId 4 和 MessageSize 0。
- 观察:从客户端发送不同的值甚至不会影响服务器输出。总是那个奇怪的数字 65501..
- 有趣:它确实有效,但是如果我只写 一个 个数字而不是两个!
知道我做错了什么吗?
我觉得你在读垃圾数据,看看mid declaration
QByteArray QByteArray::mid(int pos, int len = -1) const
它returns新对象,并且在这一行
const char * messageIdBytes = buffer.mid(0, 2);
mid
函数returns临时对象QByteArray,使用方法
转换为const char*
QByteArray::operator const char *() const
删除临时对象时,您的指针悬空。那你就是在读垃圾数据。
一件事,在这一行
buffer.mid(2, 4); // should be 2 as second argument, this is not index but length
发送原始数字从来都不是一个好主意。这可能出错的原因是:
- 去同步化
- 字节序
- 解析错误
- ...
Qt 中的最佳实践是使用QDataStream
发送和接收数据:
客户代码:
QDataStream stream(socket);
stream << MessageId << MessageSize;
服务器代码:
QDataStream stream(socket);
ushort MessageId, MessageSize;
stream.startTransaction();
stream >> MessageId >> MessageSize;
if(stream.commitTransaction())
qDebug() << "Worked:" << MessageId << MessageSize;
else
qDebug() << "Error:" << stream.status();
您可以在 Documentation
阅读更多关于 QDataStream 和阅读交易的信息
客户端应用程序通过QTcpSocket向服务器发送两个(ushort)号码:
ushort MessageId = 4;
ushort MessageSize = 0;
socket->write((const char*) &MessageId, sizeof(ushort));
socket->write((const char*) &MessageSize, sizeof(ushort));
socket->waitForBytesWritten();
Server 应用程序接收 4 字节长的消息并将其放入 QByteArray 缓冲区然后解码数字:
int bytes = socket->bytesAvailable();
QByteArray buffer = socket->read(bytes)
const char * messageIdBytes = buffer.mid(0, 2);
ushort messageId = (ushort)(*messageIdBytes);
const char * messageSizeBytes = buffer.mid(2, 4);
ushort messageSize = (ushort)(*messageSizeBytes );
qDebug() << QString("MessageId Bits: [%1], Value: [%2].").arg(QString::number(messageId, 2), QString::number(messageId));
qDebug() << QString("MessageSize Bits: [%1], Value: [%2].").arg(QString::number(messageSize, 2), QString::number(messageSize));
这给出了以下服务器输出:(为了便于阅读,我添加了空格)
MessageId Bits: [1111 1111 1101 1101], Value: [65501].
MessageSize Bits: [1111 1111 1101 1101], Value: [65501].
- 问题:服务器输出应该收到 MessageId 4 和 MessageSize 0。
- 观察:从客户端发送不同的值甚至不会影响服务器输出。总是那个奇怪的数字 65501..
- 有趣:它确实有效,但是如果我只写 一个 个数字而不是两个!
知道我做错了什么吗?
我觉得你在读垃圾数据,看看mid declaration
QByteArray QByteArray::mid(int pos, int len = -1) const
它returns新对象,并且在这一行
const char * messageIdBytes = buffer.mid(0, 2);
mid
函数returns临时对象QByteArray,使用方法
QByteArray::operator const char *() const
删除临时对象时,您的指针悬空。那你就是在读垃圾数据。
一件事,在这一行
buffer.mid(2, 4); // should be 2 as second argument, this is not index but length
发送原始数字从来都不是一个好主意。这可能出错的原因是:
- 去同步化
- 字节序
- 解析错误
- ...
Qt 中的最佳实践是使用QDataStream
发送和接收数据:
客户代码:
QDataStream stream(socket);
stream << MessageId << MessageSize;
服务器代码:
QDataStream stream(socket);
ushort MessageId, MessageSize;
stream.startTransaction();
stream >> MessageId >> MessageSize;
if(stream.commitTransaction())
qDebug() << "Worked:" << MessageId << MessageSize;
else
qDebug() << "Error:" << stream.status();
您可以在 Documentation
阅读更多关于 QDataStream 和阅读交易的信息