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++?