Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 如何以QByteArray/QDataStream的形式将数据从服务器发送到客户端_Qt_Qtcpsocket_Qbytearray_Qtcpserver_Qdatastream - Fatal编程技术网

Qt 如何以QByteArray/QDataStream的形式将数据从服务器发送到客户端

Qt 如何以QByteArray/QDataStream的形式将数据从服务器发送到客户端,qt,qtcpsocket,qbytearray,qtcpserver,qdatastream,Qt,Qtcpsocket,Qbytearray,Qtcpserver,Qdatastream,在Qt的Fortune服务器示例中,QString是通过方法sendFortune()发送的。因此,从QStringListfortunes中选择一个QString: QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_0); out << (quint16)0; out << fortunes.at(qrand() %

在Qt的Fortune服务器示例中,QString是通过方法
sendFortune()
发送的。因此,从QStringList
fortunes
中选择一个QString:

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << (quint16)0;
out << fortunes.at(qrand() % fortunes.size());
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));

QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
clientConnection->write(block);
QByteArray块;
QDataStream out(块和QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
外写(块);
是否也可以发送其他类型的数据,如文件、图像或多个字符串?还是只可能发送一个字符串


我的第二个问题:以QByteArry方式发送数据有什么好处?为什么我必须通过设置QDataStream来定义
(quint16)

您不以QDataStream方式发送数据,QDataStream是一个模拟流的类,一种传输数据的方式,如wire。 QByteArray表示数据的存储。 因此,您可以通过QByteArray发送数据。 您可以尝试QTcpSocket的名为“int write(QByteArray)”的成员函数,如您提供的示例所示。只需将图像、文件和任何其他数据转换为QByteArray即可。这里是您需要QDataStream的地方。像这样把溪流绑在堤坝上

QByteArray数据;
QDataStream out(&dat,QIODevice::WriteOnly)

并使用out填写dat


out要知道您是否已读取套接字另一端发送的所有数据,我使用
QDataStream
中的
commitTransaction()
函数:

Client::Client()
{
    ....
    connect(tcpSocket, &QIODevice::readyRead, this, &Client::readData);
    ....
}

void Client::readData()
{
    in.startTransaction();

    QString data;
    in >> data;

    if (!in.commitTransaction())
    {
        qDebug() << TAG << "incomplete: " << data;
        // readyRead will be called again when there is more data
        return;
    }

    // data is complete, do something with it
    ....
Client::Client()
{
....
连接(tcpSocket,&QIODevice::readyRead,this,&Client::readData);
....
}
void客户端::readData()
{
in.startTransaction();
QString数据;
在>>数据中;
如果(!in.commitTransaction())
{

qDebug()简单地说,客户机/服务器通信使用TCP等协议。该协议封装消息以到达目的地。消息是字节。字节可以是图像、字符串、文件等,因为所有内容都是字节。关于quint16问题,您必须了解,您需要定义发送/接收消息的规则,否则你将永远无法知道消息何时开始和何时结束。有没有任何例子?因为这是事实-我想理解它-但如果没有一些练习,很难理解…我应该使用哪个大小的字符串,哪个大小的图像或文本文件…我不知道…一些帮助会很好你没有e不必担心这些大小。请记住,tcp通信是一种流通信。因此,无论何时,您都会收到0101101010101。您必须定义规则(或使用一些应用程序协议,如http)以了解消息的开头和结尾。假设您要发送字符串“hello”。您首先写入0x00 0x00以知道它是消息的开头。然后写入hello。然后写入字符串0x05的大小。因此,您在套接字上发送00 00 68 65 6c 6c 6f 00 05。在另一侧,您将收到00 00 00 68 65 6c 6c 6f 00 05。您首先获取最后2个字节00 05,计算您期望的消息长度为5字节。那么y您从第三个字节读取,因为前两个字节是00 00,您有68 65 6c 6c 6f。这是一条长度为5的消息,因此它是有效消息。因此您有“您好”字符串。为什么这么复杂呢?因为使用tcp,你与paquets通信,你不知道需要多少paquets来传输你的数据,很明显,如果你收到了所有paquets。