2012-05-04 9 views
5

Tenía una conexión de socket con zócalos UNIX C++ donde, después de conectarme, tenía un bucle para leer byte por byte hasta que tenía el mensaje completo. Conozco los primeros dos bytes del mensaje que voy a recibir, y su longitud (15 bytes). Así que la función se veía así:Lectura de un QTcpSocket

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

Ahora estoy implementando lo mismo con QTcpSockets. se establece la conexión, y luego me llaman:

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

Así que estoy esperando hasta que haya algo de información listo yo ser leído, y luego llamar findPacket, que ahora es casi el mismo, byte a byte de lectura:

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

Se ve bastante igual, pero no funciona. Una vez que he esperado en waitForReadyRead, entro en el bucle de findPacket y puedo leer los primeros 4 bytes recibidos. Después de eso, no se reciben más datos. Permanece dentro del bucle de findPacket comprobando nuevamente, y nuevamente, y de nuevo, pero la función de lectura siempre devuelve 0 bytes leídos. No se recibió nueva información. Lo cual es imposible, porque el servidor está enviando el mismo paquete una vez cada pocos ms, así que incluso si pierdo algunos datos, eventualmente debería leer algo.

Entonces, ¿qué estoy haciendo mal? ¿Debo esperar de una manera diferente? ¿Debo esperar otra vez la primera vez que la función de lectura devuelve 0 bytes de lectura? ¿Cuál es la diferencia entre esta función de lectura y las bibliotecas de C++?

Respuesta

0

Finalmente, el problema fue tratar de leer todo el tiempo en lugar de esperar nuevos datos después del primer cero devuelto por la función de lectura. ¡Hacer eso funciona como un encanto!