2012-05-04 22 views
5

Miałem połączenie z gniazdem z gniazdami C++ systemu UNIX, gdzie po podłączeniu miałem pętlę do czytania bajt po bajcie, dopóki nie miałem pełnego msg. Znam dwa pierwsze bajty komunikatu, który otrzymam, i jego długość (15 bajtów). Tak więc funkcja wyglądała następująco:Czytanie 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; 
} 

Teraz wdrażam to samo z QTcpSockets. Połączenie zostanie ustanowione, a potem zadzwonić:

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

Więc czekam aż istnieją pewne informacje gotowy yo odczytać, a następnie zadzwonić findPacket, która obecnie jest prawie taki sam, czytanie bajt po bajcie:

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

Wygląda całkiem podobnie, ale nie działa. Kiedy czekałem na czekanie, FORReadyRead, wchodzę w pętlę findPacket i mogę odczytać pierwsze 4 bajty odebrane. Następnie nie są już odbierane żadne dane. Pozostaje on w pętli findPacket ponownie sprawdzając, i znowu, i znowu, ale funkcja odczytu zawsze zwraca 0 bajtów odczytanych. Brak nowych informacji. Co jest niemożliwe, ponieważ serwer wysyła ten sam pakiet raz na kilka ms, więc nawet jeśli stracę trochę danych, w końcu powinienem coś czytać.

Więc, co robię źle? Czy powinienem czekać w inny sposób? Czy powinienem poczekać jeszcze raz, gdy funkcja odczytu po raz pierwszy zwróci 0 bajtów odczytanych? Jaka jest różnica między tą funkcją odczytu a bibliotekami C++?

Odpowiedz

0

Wreszcie, problem polegał na próbie odczytu przez cały czas, zamiast oczekiwania na nowe dane po pierwszym zera zwróconym przez funkcję odczytu. Działa to jak urok!