Вопрос

I had a socket connection with UNIX C++ sockets where, after connecting, I had a loop for reading byte by byte until I had the full msg. I know the first two bytes of the message I'm going to receive, and its length (15 bytes). So the function looked like:

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;
}

Now I'm implementing the same with QTcpSockets. Connection is established, and then I call:

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

So I'm waiting until there is some info ready yo be read, and then call findPacket, which is now almost the same, reading byte by byte:

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;
}

Looks pretty the same, but it doesn't work. Once I have waited on waitForReadyRead, I enter findPacket's loop and I am able to read the first 4 bytes received. After that, no more data is received. It remains inside findPacket's loop checking again, and again, and again, but read function always return 0 bytes read. No new info is received. Which is impossible, because server is sending the same packet once every few ms, so even if I loss some data, eventually I should be reading something.

So, what I am doing wrong? Should I wait in a different way? Should I wait again the first time read function returns 0 bytes read? What's the difference between this read function and the C++ libraries one?

Это было полезно?

Решение

Finally, the problem was trying to read all the time instead of waiting for new data after the first zero returned by the read function. Doing that works like a charm!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top