gpt4 book ai didi

c++ - QTcpSocket::readAll() 为空

转载 作者:行者123 更新时间:2023-11-30 03:31:03 25 4
gpt4 key购买 nike

我是 Qt 的新手并且有点挣扎。我正在尝试使用 QTcpSocket 将字符串从客户端发送到服务器。

客户端:

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << name;

tSock->connectToHost(ipAddress, portNumb.toInt());
tSock->waitForConnected();
tSock->write(block); // block is not empty
tSock->flush();

服务器端:

void Server::readyRead()
{
QByteArray block;
QDataStream out(&block, QIODevice::ReadOnly);
out << tcpSocket->readAll();
QString name(block); // block is empty
players.insert(name, tcpSocket);
std::cout << "name: " << name.toStdString(); // TODO remove
}

服务器端程序在接收到数据时进入readyRead(),但是block是空的,虽然在客户端tSock->write(block) 被称为...问题似乎在哪里?我将不胜感激任何帮助。谢谢!

最佳答案

编辑:你的错误是你以ReadOnly模式打开out数据流,但是尝试write 接收到的字节数组:

void Server::readyRead()
{
QByteArray block;
QDataStream out(&block, QIODevice::ReadOnly); // !mistake, WriteOnly mode is needed
out << tcpSocket->readAll(); // this is write operation
//...
}

附加:请注意有 Serialization mechanism of Qt Data Types这在这种情况下很有用:

tSock->write(block); // this is write just a raw data of the block, not the "QByteArray"

您可以使用流操作将必要的 Qt 数据类型直接写入套接字,而无需转换为 QByteArray:

// Connect firstly
tSock->connectToHost(ipAddress, portNumb.toInt());
tSock->waitForConnected();

// Then open a data stream for the socket and write to it:
QDataStream out(tSock, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << name; // write string directly without a convertion to QByteArray

// Then you may
tSock->flush();

在Client端,然后在Server端使用类似的流操作:

void Server::readyRead()
{
QString name;
QDataStream in(tcpSocket, QIODevice::ReadOnly /*or QIODevice::ReadWrite if necessary */);
in.setVersion(QDataStream::Qt_4_0);
in >> name; // read the string
//...
}

也可以读/写对象到另一个 Qt 的 I/O 设备:QFile , QSerialPort , QProcess , QBuffer和其他人。

编辑 2:不能保证在 readyRead 信号上您会收到已发送的完整包裹。因此请参见下面的示例。


请注意,在实际情况下(当您在客户端-服务器通信中有多个不同的数据包,并且不知道您收到了几个可能的数据包中的哪一种时)通常有使用了比较复杂的算法,因为在一次通信的readyRead事件上可能会出现以下情况:

  1. 收到完整数据包
  2. 只收到部分包裹
  3. 一起收到了几个包裹

算法的变体(Qt 4 Fortune Client Example):

void Client::readFortune() // on readyRead
{
QDataStream in(tcpSocket);
in.setVersion(QDataStream::Qt_4_0);

if (blockSize == 0) {
if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
return;

in >> blockSize;
}

if (tcpSocket->bytesAvailable() < blockSize)
return;

QString nextFortune;
in >> nextFortune;

//...
}

Qt 4.0 是太旧的 Qt 版本,因此另请参阅 Qt 5.9 Fortune Client Example

关于c++ - QTcpSocket::readAll() 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44527759/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com