Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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
C++ 从QLocalSocket读取超过2048字节_C++_Sockets_Qt5 - Fatal编程技术网

C++ 从QLocalSocket读取超过2048字节

C++ 从QLocalSocket读取超过2048字节,c++,sockets,qt5,C++,Sockets,Qt5,我在从QLocalSocket读取超过2048字节时遇到问题。 这是我的服务器端代码: clientConnection->flush(); // <-- clientConnection is a QLocalSocket QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_0); out << (quint16)

我在从QLocalSocket读取超过2048字节时遇到问题。 这是我的服务器端代码:

clientConnection->flush();  // <-- clientConnection is a QLocalSocket

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_5_0);
out << (quint16)message.size() << message;  // <--- message is a QString

qint64 c = clientConnection->write(block);
clientConnection->waitForBytesWritten();
if(c == -1)
    qDebug() << "ERROR:" << clientConnection->errorString();

clientConnection->flush();
clientConnection->flush();

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_5_0);

out << (quint16)0;
out << message;
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
qDebug() << "Bytes client should read" << (quint16)(block.size() - sizeof(quint16));

qint64 c = clientConnection->write(block);
clientConnection->waitForBytesWritten();
QDataStream in(sock);
in.setVersion(QDataStream::Qt_5_0);

while(sock->bytesAvailable() < sizeof(quint16)){
    sock->waitForReadyRead();
}

quint16 btr;
in >> btr;

qDebug() << "Need to read" << btr << "and we have" << sock->bytesAvailable() << "in sock";
while(sock->bytesAvailable() < btr){
    sock->waitForReadyRead();
}

in >> received_message;

qDebug() << received_message;
客户端代码:

clientConnection->flush();  // <-- clientConnection is a QLocalSocket

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_5_0);
out << (quint16)message.size() << message;  // <--- message is a QString

qint64 c = clientConnection->write(block);
clientConnection->waitForBytesWritten();
if(c == -1)
    qDebug() << "ERROR:" << clientConnection->errorString();

clientConnection->flush();
clientConnection->flush();

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);

out.setVersion(QDataStream::Qt_5_0);

out << (quint16)0;
out << message;
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
qDebug() << "Bytes client should read" << (quint16)(block.size() - sizeof(quint16));

qint64 c = clientConnection->write(block);
clientConnection->waitForBytesWritten();
QDataStream in(sock);
in.setVersion(QDataStream::Qt_5_0);

while(sock->bytesAvailable() < sizeof(quint16)){
    sock->waitForReadyRead();
}

quint16 btr;
in >> btr;

qDebug() << "Need to read" << btr << "and we have" << sock->bytesAvailable() << "in sock";
while(sock->bytesAvailable() < btr){
    sock->waitForReadyRead();
}

in >> received_message;

qDebug() << received_message;
QDataStream-in(sock);
in.setVersion(QDataStream::Qt_5_0);
while(sock->bytesavable()waitForReadyRead();
}
16 btr;
在>>btr;
qDebug()已收到_消息;
qDebug()
out.setVersion(QDataStream::Qt_5_0);
out>
以反序列化对象。因此,在确保接收到所有数据之前,您不能使用它。这让我们想到:
  • TCP没有用于分离“记录”中数据的内置机制。您不能只发送一些字节,后跟一个“记录标记”,告诉接收者他已经收到了与记录相关的所有数据。TCP提供的是原始字节流。最后,您可以(半)关闭连接,向另一个对等方发出传输结束的信号
  • 1+2意味着您必须使用其他机制(在接收方)来了解您是否已经拥有所需的所有数据,或者您必须等待更多数据。例如,您可以引入带内标记,如
    \r\n
    (如IRC或-在一定程度上-HTTP do)

    《财富》示例中的解决方案是在“实际”数据(带有《财富》消息的序列化QString)前面加上该数据的长度(以字节为单位);然后发送长度(16位整数),后跟数据本身

    接收器首先读取长度;然后它读取了那么多字节,然后它知道它可以解码财富。如果没有足够的可用数据(长度-即,您收到的数据少于2个字节-和有效负载本身),客户机将什么也不做,等待更多数据

    请注意:

    • 这种设计并不是新的:大多数协议都是这样做的。在“标准”TCP/IP堆栈中,TCP、IP、Ethernet等在其“头”中都有一个字段,用于指定有效负载(或整个“记录”)的长度
    • “length”的传输使用一个以特定字节顺序发送的16位无符号整数:它不是memcpy()d进入缓冲区,而是QDataStream用于存储和读取它。虽然这看起来很琐碎,但实际上已经完成了所使用协议的定义
    • 如果QDataStream能够从短读取中恢复(即通过抛出异常并将数据留在设备中),则不需要发送有效负载的长度,因为QDataStream已经发送字符串的长度(作为32位无符号双端整数),后跟UTF-16字符
    out.setVersion(QDataStream::Qt_5_0);
    out>
    以反序列化对象。因此,在确保接收到所有数据之前,您不能使用它。这让我们想到:
  • TCP没有用于分离“记录”中数据的内置机制。您不能只发送一些字节,后跟一个“记录标记”,告诉接收者他已经收到了与记录相关的所有数据。TCP提供的是原始字节流。最后,您可以(半)关闭连接,向另一个对等方发出传输结束的信号
  • 1+2意味着您必须使用其他机制(在接收方)来了解您是否已经拥有所需的所有数据,或者您必须等待更多数据。例如,您可以引入带内标记,如
    \r\n
    (如IRC或-在一定程度上-HTTP do)

    《财富》示例中的解决方案是在“实际”数据(带有《财富》消息的序列化QString)前面加上该数据的长度(以字节为单位);然后发送长度(16位整数),后跟数据本身

    接收器首先读取长度;然后它读取了那么多字节,然后它知道它可以解码财富。如果没有足够的可用数据(长度-即,您收到的数据少于2个字节-和有效负载本身),客户机将什么也不做,等待更多数据

    请注意:

    • 这种设计并不是新的:大多数协议都是这样做的。在“标准”TCP/IP堆栈中,TCP、IP、Ethernet等在其“头”中都有一个字段,用于指定有效负载(或整个“记录”)的长度
    • “length”的传输使用一个以特定字节顺序发送的16位无符号整数:它不是memcpy()d进入缓冲区,而是QDataStream用于存储和读取它。虽然这看起来很琐碎,但实际上已经完成了所使用协议的定义
    • 如果QDataStream能够从短读取中恢复(即通过抛出异常并将数据留在设备中),则不需要发送有效负载的长度,因为QDataStream已经发送字符串的长度(作为32位无符号双端整数),后跟UTF-16字符
    您必须检查可用字节数是否等于或大于您期望接收的字节数。通常情况下,如果没有足够的数据可读取,您可以从readyRead插槽返回,当更多数据到来时,它将再次被调用。@Archie bytesAvailable()返回4KB(我希望是2KB),所以这应该可以。至于第二个电话,那是办不到的。我需要在一次调用中完成所有操作(根据Qt文档,这是可能的,我只需要等待数据,我就是这么做的)。您必须检查bytesAvailable是否等于或大于您希望接收的任何值。通常情况下,如果没有足够的数据可读取,您可以从readyRead插槽返回,当更多数据到来时,它将再次被调用。@Archie bytesAvailable()返回4KB(我希望是2KB),所以这应该可以。至于第二个电话,那是办不到的。我需要在一次通话中完成所有工作(根据Qt文档,这是可能的,我只需要等待数据,我会这样做)。谢谢您的回复。我更新了我的代码