QTcpSocket接收传输 [英] QTcpSocket receiving transfer

查看:647
本文介绍了QTcpSocket接收传输的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在接收转帐时遇到问题.

I'm having issues with receiving a transfer.

QTcpSocket-> readAll()时,它读取的字节数不足.当我发送15k字节时,它只读取其中的一部分,然后什么也不做.我在做什么错了?

QTcpSocket->readAll() does not read enough bytes when I'm sending to it. When I send 15k bytes, it reads only some part of it and then does nothing. What am I doing wrong?

QByteArray array;

array = socket->readAll(); //just reads some part, not fully.

为什么会这样?

推荐答案

当您调用readAll()时,套接字很可能尚未收到所有数据.这是因为TCP通信发生在小数据包中(每个数据包大约有1KB的数据,具体取决于很多东西).这些数据包组成一个流,通信线路的另一端将字节写入其中.您必须在接收侧组装它们.组装它们的方式必须在协议中定义.

Most probably the socket didn't receive all data yet when you call readAll(). This is because of TCP communication happens in small packets (each having around 1KB of data, depending on a lot of things). These packets make up a stream in which the other end of the communication line writes bytes into. You have to assemble them on the receiving side. How you assemble them has to be defined in a protocol.

要解决此问题,必须先等待所有预期的数据,然后再进行组装.有时,除非您读取数据(取决于协议),否则不知道期望多少数据.

To solve this issue, you have to wait for all expected data before assembling it. Sometimes it is not known how much data is expected unless you read it (depending on the protocol).

比方说,您要实现一个协议,其中规定:直到换行符为止的所有内容,我们都称为 message ".现在,您希望收到这样的消息.这是通过连续读取并附加到目标缓冲区(例如您的QByteArray)直到出现换行符来完成的.但是,还有另一件事:当您期望第二个 message 时,它可能紧接在TCP流中的第一个消息之后,因此,您不仅读取了第一条消息的末尾,而且还读取了第二个开始.请记住这一点.

Let's say you want to implement a protocol which says "everything until a line break is something we call a message". Now you want to receive such a message. This is done by successively reading and appending to a target buffer (like your QByteArray) until there comes a line break. However, there is another thing: When you expect a second message, it can be immediately after the first one in the TCP stream, so you just read not only the end of the first message, but also the beginning of the second. Just keep this in mind.

当不处理信号插槽连接时,可以为此类换行符分隔的消息编写一个同步接收器,如下所示:

When not dealing with signal slot connection, you can write a synchronous receiver for such newline-separated messages like this:

QByteArray array;

while(!array.contains('\n')) {
    socket->waitForReadyRead();
    array += socket->readAll();
}

int bytes = array.indexOf('\n') + 1;     // Find the end of message
QByteArray message = array.left(bytes);  // Cut the message
array = array.mid(bytes);                // Keep the data read too early

processMessage(message);

处理QTcpSocket::readyRead()时,您可以执行类似的操作.

When handling QTcpSocket::readyRead(), you can do something similar.

void MyClass::socketReadyRead() // connected to QTcpSocket::readyRead() signal
{
    array += socket->readAll();

    if(array.contains('\n')) {
        int bytes = array.indexOf('\n') + 1;     // Find the end of message
        QByteArray message = array.left(bytes);  // Cut the message
        array = array.mid(bytes);                // Keep the data read too early

        processMessage(message);

        socketReadyRead();                       // re-call myself to process more
    }
}


当您要读取通过一个TCP连接发送的所有内容(直到被对等方关闭)时,可以以阻塞方式等待此事件,也可以处理连接到正确信号的插槽中的数据:.


When you want to read everything sent via one TCP connection (until it gets closed by the peer), you can wait for this event either in a blocking way or process the data in a slot connected to the proper signal: QTcpSocket::disconnected.

封锁:

socket->waitForDisconnected();
QByteArray array = socket->readAll();

无阻塞(使用插槽处理信号):

Non-blocking (handling signals using slots):

void MyClass::socketReadyRead() // connected to QTcpSocket::readyRead() signal
{
    array += socket->readAll();
    // Do NOT process yet!
}

void MyClass::socketDisconnected() // connected to QTcpSocket::disconnected() signal
{
    processMessage(array);
}

可选的非阻塞解决方案(基本上相同):

Alternative non-blocking solution (essentially the same):

// You don't have to connect to QTcpSocket::readyRead() signal in this case

void MyClass::socketDisconnected()
{
    processMessage(socket->readAll());
}

这篇关于QTcpSocket接收传输的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆