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