2012-05-04 3 views
5

UNIX C++ 소켓과의 소켓 연결이 있습니다. 연결 후 전체 메시지가 나올 때까지 바이트 단위로 읽는 루프가 있습니다. 나는 내가받을 메시지의 처음 두 바이트와 그 길이 (15 바이트)를 안다. 따라서 함수는 다음과 같이 보입니다 :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; 
} 

이제 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의 루프를 다시 검사하고, 다시, 다시 반복하지만, read 함수는 항상 0 바이트를 반환합니다. 새로운 정보가 수신되지 않습니다. 불가능한 이유는 서버가 몇 밀리 초마다 동일한 패킷을 보내므로 데이터가 손실 되더라도 결국에는 뭔가를 읽어야한다는 것입니다.

그래서 내가 뭘 잘못하고있는 걸까요? 다른 방법으로 기다려야합니까? 처음으로 read 함수가 0 바이트를 읽었을 때 다시 기다려야합니까? 이 읽기 함수와 C++ 라이브러리 라이브러리의 차이점은 무엇입니까?

답변

0

마지막으로, 문제는 읽기 기능으로 반환 된 첫 번째 0 이후에 새 데이터를 기다리는 대신 항상 읽으려고했습니다. 그 일을하는 것은 매력처럼 작동합니다!