Pregunta

Estoy construyendo un programa servidor que el intercambio de datos a través de TCP cliente y y estoy teniendo problemas para enviar un ACK-confirmación desde el servidor al cliente cuando una operación es exitosa. Me las he arreglado para enviar una estructura con varios miembros desde el cliente al servidor, el servidor debe responder enviando un número entero de confirmar la identificación de la estructura de vuelta al cliente.

En server.c Tengo esta función:

int sendACK(int socket, int ack_int){

    int com_result;
    int ACK = htonl(ack_int);

    printf("\n\tSending ACK with value: %i", ack_int);

    com_result = send(socket, &ACK, sizeof(ACK), 0);

    if (com_result == -1) {
        perror("\n\t[ERROR] Send ACK");
        return 0;
    }

    return 1;

}

Esta función es llamada por otra función en server.c como esto:

int ACK = myStruct->ID;
sendACK(socket, ACK);

Por lo tanto, si sólo he recibido una estructura con ID: 2, la salida será:
Envío de ACK con el valor: 2

En client.c que recibo ACK como esto:

int ACK = 0;
data_size  = sizeof(myStruct.ID);
com_result = read(client_socket, &ACK, data_size);
ACK = ntohl(ACK);

if (com_result == -1) {
    perror("\n\t[ERROR] Read");
} else {
    printf("\n\tRecieved %i of %i bytes", com_result, data_size);
    if (ACK != myStruct.ID) {
        printf("\n\t[ERROR] Invalid ACK (%i).", ACK);
    }
}

Sin embargo, el ACK es siempre recibió con un valor de 1, por lo que la salida de cliente es:
Recibido 4 de 4 bytes
ERROR] no válida ACK (1).

¿Por qué no es el número entero recibido con un valor de 2 , y cómo puedo solucionar este problema?

¿Fue útil?

Solución

Esto es más probable no el problema, pero creo que la segunda línea en el fragmento client.c a continuación debe tener sizeof (ACK).

int ACK = 0;
data_size  = sizeof(ACK); // was: sizeof(myStruct.ID);
com_result = read(client_socket, &ACK, data_size);
ACK = ntohl(ACK);

También, dependiendo de su flujo de datos, es posible que en realidad estás leyendo correctamente y el ACK es la respuesta de un paquete que ya haya enviado?

Otros consejos

Nunca se debe enviar valores enteros de este tipo, es necesario prestar más atención a la serialización. Esto puede fallar si, por ejemplo, el sizeof (int) es diferente en la máquina de envío de la que recibe, en cuyo caso se lee el número incorrecto de bytes.

Es mejor que tener más cuidado y serializar campos de un byte a la vez.

Con el fin de depurarlo, puede utilizar Wireshark . Ejecutar Wireshark y establecer sus opciones para escuchar el puerto requerido. Usted verá lo que realmente se envía dentro del paquete por la red. Esto le permitirá entender si el problema es con el servidor, el cliente o ambos.

No puedo imaginar nada mal con el código que ha pegado encima. Yo sugeriría salir Wireshark, ni otra toma programa de rastreo, y mirando a los bits en el cable.

Me gustaría comprobar que el código principal emisor / receptor está manejando la cantidad correcta de datos.

Si el remitente envía 20 bytes seguido de un ACK de cuatro bytes, pero el receptor sólo lee 16 antes de intentar leer el ACK, usted podría tener este tipo de problemas.

Si va a enviar datos de longitud variable (es decir. Con un prefijo ByteCount) una confusión común acerca de si el ByteCount se transmite en realidad incluye los bytes adicionales necesarios para enviar el número de bytes ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top