读取 QTcpSocket

Posted

技术标签:

【中文标题】读取 QTcpSocket【英文标题】:Reading a QTcpSocket 【发布时间】:2012-05-04 06:56:46 【问题描述】:

我有一个与 UNIX C++ 套接字的套接字连接,在连接后,我有一个循环,用于逐字节读取,直到获得完整的 msg。我知道我将要接收的消息的前两个字节,以及它的长度(15 个字节)。所以函数看起来像:

bool mastControl::findPacket(int sockfd, st_messageMastToPc * messageReceived, bool * connected) 

    int n = 0;
    bool messageFound = false;
    char * buffer = (char *) messageReceived;

    unsigned int pos = 0;

    while ( ((n = read(sockfd, &(buffer[pos]), 1)) > 0) and not messageFound) 

         if (n == 1) 
            pos++;

            if ( (pos == 1) && (buffer[0] == 0x02))  // First byte to receive
                std::cout << "INFO - Rcv1" << std::endl;
             else if ( (pos == 2) && (buffer[1] == 0x33) )  // Second byte
                std::cout << "INFO - Rcv2" << std::endl;
             else if (pos >= uiMessageMastToPcSize)  // Full msg received
                messageFound = true;
                std::cout << "INFO - Complete message received" << std::endl;
             else if (pos <= 2)  // Wrong values for the first 2 bytes
                std::cout << "WARN - Reseting (byte " << pos << " -> " << int(pos) << ")" << std::endl;
                pos = 0;
            
        
    

    if (n < 0)
        //EROR
        *connected = false;
    

    return messageFound;

现在我正在使用 QTcpSockets 实现相同的功能。建立连接,然后我调用:

if(socket->waitForReadyRead(Global::tiempoMaximoDeEsperaParaRecibirDatosMastil))
                /* Read socket to find a valid packet */
                if (findPacket(socket, &messageReceived)) 
                    qDebug()<<"New packet found!";
//...


所以我等到有一些信息准备好被读取,然后调用 findPacket,现在几乎相同,逐字节读取:

bool mastControl::findPacket(QTcpSocket *socket, st_messageMastToPc * messageReceived) 
    int n = 0;
    bool messageFound = false;
    char * buffer = (char *) messageReceived;
    unsigned int pos = 0;

    while ( ((n = socket->read(&(buffer[pos]), 1)) >= 0) and not messageFound) 
        if (n == 1) 
            qDebug()<<"Recibido: "<<buffer[pos]<<", en pos: "<<pos;
            pos++;
            if ( (pos == 1) && (buffer[0] == 0x022)) 
                qDebug()<<"0x02 in first position";
//                std::cout << "INFO - Rcv1" << std::endl;
             else if ( (pos == 2) && (buffer[1] == 0x33) ) 
                qDebug()<<"0x33 in second";
                std::cout << "INFO - Rcv2" << std::endl;
             else if (pos >= uiMessageMastToPcSize) 
                messageFound = true;
                std::cout << "INFO - Complete message received" << std::endl;
             else if (pos <= 2) 
                std::cout << "WARN - Reseting (byte " << pos << " -> " << int(pos) << ")" << std::endl;
                pos = 0;
            
        
    

    if (n < 0)
      qDebug()<< "Disconnected. Reason: " << socket->errorString();
    

    return messageFound;

看起来几乎一样,但它不起作用。一旦我等待 waitForReadyRead,我进入 findPacket 的循环,我就能够读取接收到的前 4 个字节。之后,不再接收数据。它仍然在 findPacket 的循环检查中,一次又一次,但读取函数总是返回读取的 0 字节。没有收到新信息。这是不可能的,因为服务器每隔几毫秒发送一次相同的数据包,所以即使我丢失了一些数据,最终我应该会读取一些东西。

那么,我做错了什么?我应该以不同的方式等待吗?我应该再次等待读取函数第一次返回读取的 0 字节吗?这个读取函数和 C++ 库有什么区别?

【问题讨论】:

【参考方案1】:

最后,问题在于尝试一直读取,而不是在读取函数返回的第一个零之后等待新数据。这样做就像一种魅力!

【讨论】:

以上是关于读取 QTcpSocket的主要内容,如果未能解决你的问题,请参考以下文章

用C#读取XML文件,怎么可以循环读取

TypeError:无法在 gitlab 中读取未定义的属性(读取“读取”)

R读取xlsx文件

java 读取大容量文件,内存溢出?怎么按几行读取,读取多次。

2015版vs c#读取excel代码

java从xml读取数据更快还是从数据库里读取数据更快?