Question

Je construis un client et un programme de serveur qui échange des données sur TCP et je ne parviens pas à envoyer un accusé de réception-confirmation du serveur au client lorsqu'une opération est réussie. J'ai réussi à envoyer un struct avec divers membres du client au serveur, le serveur doit répondre en envoyant un entier confirmant l'ID de la struct au client.

Dans server.c Je cette fonction:

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;

}

Cette fonction est appelée par une autre fonction dans server.c comme ceci:

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

Alors, si je venez de recevoir un struct avec ID: 2, la sortie sera:
Envoi ACK avec la valeur: 2

Dans client.c je reçois l'ACK comme ceci:

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

Mais l'ACK est toujours recieved avec une valeur de 1, de sorte que la sortie du client est:
REÇU 4 4 octets
ERREUR] invalide ACK (1).

Pourquoi ne pas l'entier recieved avec une valeur de 2 , et comment puis-je résoudre ce problème?

Était-ce utile?

La solution

Ceci est très probablement pas le problème, mais je crois que la 2ème ligne dans votre extrait de client.c ci-dessous doit être sizeof (ACK).

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

En outre, en fonction de votre flux de données, est-il possible que vous lisez en fait correctement et l'accusé de réception est la réponse d'un paquet qui vous avez envoyé précédemment?

Autres conseils

Vous ne devriez jamais envoyer des valeurs entières comme celui-ci, vous devez payer plus d'attention à la sérialisation. Cela pourrait échouer si, par exemple, le sizeof (int) est différent sur la machine émettrice de la réception d'un, dans ce cas, vous lirez le nombre incorrect d'octets.

Il est préférable de prendre plus de soin et champs sérialiser un octet à la fois.

Pour déboguer, vous pouvez utiliser Wireshark . Exécuter Wireshark et définir ses options pour écouter le port requis. Vous verrez ce qui a été envoyé à l'intérieur du paquet à travers le réseau. Cela vous permettra de comprendre si le problème est avec le serveur, le client ou les deux.

Je ne peux pas comprendre quelque chose de mal avec le code que vous avez collé ci-dessus. Je vous suggère de sortir Wireshark, ou un autre programme de traçage prise, et en regardant les bits sur le fil.

Je vérifie que votre code principal émetteur / récepteur gère la bonne quantité de données.

Si votre expéditeur envoie 20 octets suivi d'un quatre octets ACK mais le récepteur ne lit que 16 avant d'essayer de lire l'ACK, vous pourriez avoir ce genre de problème.

Si vous envoyez des données de longueur variable (ie. Avec un préfixe bytecount) une confusion commune pour savoir si le bytecount transmis comprend en fait les octets supplémentaires nécessaires pour envoyer le nombre d'octets ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top