5

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?

4

1 回答 1

0

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!

于 2012-05-04T07:57:56.930 回答