Клиент / сервер: целое число всегда принимается как 1 (C-программирование) - PullRequest
0 голосов
/ 19 ноября 2009

Я создаю клиентскую и серверную программу, которая обменивается данными по TCP, и у меня возникают проблемы с отправкой ACK-подтверждения с сервера обратно клиенту, когда операция прошла успешно. Мне удалось отправить структуру с различными членами от клиента на сервер, затем сервер должен ответить, отправив целое число, подтверждающее идентификатор структуры, обратно клиенту.

В server.c у меня есть эта функция:

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;

}

Эта функция вызывается другой функцией в server.c, например:

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

Итак, если я только что получил структуру с ID: 2, результат будет:
Отправка ACK со значением: 2

В client.c я получаю ACK следующим образом:

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

Но ACK всегда принимается со значением 1, поэтому вывод от клиента:
Получено 4 из 4 байтов
ОШИБКА] Неверный ACK (1).

Почему целое число не получено со значением 2 , и как я могу это исправить?

Ответы [ 5 ]

3 голосов
/ 19 ноября 2009

Скорее всего, это не проблема, но я считаю, что вторая строка в вашем фрагменте client.c ниже должна быть sizeof (ACK).

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

Кроме того, в зависимости от вашего потока данных, возможно ли, что вы действительно правильно читаете, и ACK - это ответ от пакета, который вы отправили ранее?

1 голос
/ 19 ноября 2009

Для отладки вы можете использовать wireshark . Выполните wireshark и установите его параметры для прослушивания требуемого порта. Вы увидите, что на самом деле было отправлено внутри пакета через сеть. Это позволит вам понять, связана ли проблема с сервером, клиентом или обоими.

1 голос
/ 19 ноября 2009

Вы никогда не должны отправлять целые значения, как это, вам нужно больше внимания уделять сериализации. Это может произойти сбой, если, например, sizeof (int) отличается на отправляющем компьютере от принимающего, и в этом случае вы будете читать неправильное количество байтов.

Лучше позаботиться и сериализовать поля по одному байту за раз.

0 голосов
/ 19 ноября 2009

Я бы проверил, что ваш основной код отправителя / получателя обрабатывает правильный объем данных.

Если ваш отправитель отправляет 20 байтов, за которыми следует четырехбайтовый ACK, но получатель читает только 16, прежде чем пытаться прочитать ACK, у вас может быть такая проблема.

Если вы отправляете данные переменной длины (т. Е. С префиксом bytecount), возникает распространенное заблуждение относительно того, действительно ли передаваемый байтовый счет включает в себя дополнительные байты, необходимые для отправки количества байтов ...

0 голосов
/ 19 ноября 2009

Я не могу понять, что-то не так с кодом, который вы вставили выше. Я бы посоветовал достать Wireshark или другую программу отслеживания сокетов и посмотреть на биты на проводе.

...