Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.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++ QTcpSocket接收传输_C++_Qt_Qtcpsocket - Fatal编程技术网

C++ QTcpSocket接收传输

C++ QTcpSocket接收传输,c++,qt,qtcpsocket,C++,Qt,Qtcpsocket,我在接受调动方面遇到了问题 发送到QTcpSocket->readAll()时读取的字节不足。当我发送15k字节时,它只读取其中的一部分,然后什么也不做。我做错了什么 QByteArray array; array = socket->readAll(); //just reads some part, not fully. 为什么会发生这种情况?调用readAll()时,很可能套接字尚未接收到所有数据。这是因为TCP通信发生在小数据包中(每个数据包大约有1KB的数据,这取决于很多事情

我在接受调动方面遇到了问题

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

QByteArray array;

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

为什么会发生这种情况?

调用
readAll()
时,很可能套接字尚未接收到所有数据。这是因为TCP通信发生在小数据包中(每个数据包大约有1KB的数据,这取决于很多事情)。这些数据包组成一个流,通信线路的另一端在其中写入字节。你必须在接收端组装它们。如何组装它们必须在协议中定义

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

假设您想要实现一个协议,该协议说“在断线之前的一切都是我们称之为消息的东西”。现在你想收到这样的信息。这是通过连续读取并附加到目标缓冲区(如
QByteArray
)直到出现换行来完成的。然而,还有另一件事:当您期望第二条消息时,它可以紧跟在TCP流中的第一条消息之后,因此您不仅要读取第一条消息的结尾,还要读取第二条消息的开头。记住这一点

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

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()时,可以执行类似的操作

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连接发送的所有数据时(直到对等方关闭它),您可以以阻塞方式等待此事件,或者处理连接到正确信号的插槽中的数据:
QTcpSocket::disconnected

阻塞:

socket->waitForDisconnected();
QByteArray array = socket->readAll();
非阻塞(使用插槽处理信号):

替代非阻塞解决方案(基本相同):


调用
readAll()
时,很可能套接字尚未收到所有数据。这是因为TCP通信发生在小数据包中(每个数据包大约有1KB的数据,这取决于很多事情)。这些数据包组成一个流,通信线路的另一端在其中写入字节。你必须在接收端组装它们。如何组装它们必须在协议中定义

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

假设您想要实现一个协议,该协议说“在断线之前的一切都是我们称之为消息的东西”。现在你想收到这样的信息。这是通过连续读取并附加到目标缓冲区(如
QByteArray
)直到出现换行来完成的。然而,还有另一件事:当您期望第二条消息时,它可以紧跟在TCP流中的第一条消息之后,因此您不仅要读取第一条消息的结尾,还要读取第二条消息的开头。记住这一点

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

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()时,可以执行类似的操作

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连接发送的所有数据时(直到对等方关闭它),您可以以阻塞方式等待此事件,或者处理连接到正确信号的插槽中的数据:
QTcpSocket::disconnected

阻塞:

socket->waitForDisconnected();
QByteArray array = socket->readAll();
非阻塞(使用插槽处理信号):

替代非阻塞解决方案(基本相同):


这个代码什么时候执行?处理信号
readyRead()
或在
waitForReadyRead()
或其他之后时?它位于QTcpSocket的readyRead()插槽中。此代码何时执行?当处理信号时,
readyRead()
或在
waitForReadyRead()
或其他之后?它在QTcpSocket的readyRead()插槽中。嗨,我真的不知道它会有多长时间,也不知道它会以什么结束,我正在发送原始二进制格式。我知道如何使用Winsock或POSIX套接字,但对qt.@OvérFlôwz来说是个新手。您必须提前知道长度,或者通过在接收数据时检测端点来知道长度。你传输什么二进制格式?如何在POSIX套接字中等待整个消息?我正在以1024的大小逐块读取消息,当消息到达末尾时,返回0或-1(不记得是真的),然后将所有数据写入磁盘。我只发送原始数据,不是格式或其他任何东西,只是原始数据,我不知道会是什么。什么结束了?TCP连接何时关闭?我在问,因为TCP流没有类似于“数据结束”的东西,但是您可以关闭整个strem(当然,这样您就不能在同一个连接上接收更多的数据)。是否在汇编中进行了此操作,请检查您是否愿意。recv_循环:invoke recv,[hSock],buffer,1024,0 cmp eax,0 jle end_循环invoke WriteFile,[file_handle],buffer,eax,wbytes,0 jmp recv_循环end_循环:;在这里完成。嗨,我真的不知道要多长时间,或者它会以什么结束,我正在发送原始二进制格式。我知道如何使用Winsock或POSIX套接字,但对qt.@OvérFlôwz来说是个新手。您必须提前知道长度,或者通过在接收数据时检测端点来知道长度。你传输什么二进制格式?如何在POSIX套接字中等待整个消息?我正在以1024的大小逐块读取消息,当消息到达末尾时,返回0或-1(不记得是真的),然后将所有数据写入磁盘。我只发送原始数据,不是格式或其他任何东西,只是原始数据,我不知道会是什么。什么结束了?什么时候