uint16_t в массиве char

Для школьного проекта мне нужно разработать TFTP-сервер на C. Я должен собрать пакет в массиве char следующим образом:

 2 bytes    2 bytes    n bytes
+--------+-----------+--------+
|  CODE  |  Block #  |  Data  |
+--------+-----------+--------+

Вот как я собираю этот пакет:

int tftp_make_data(char *buffer, size_t *length, uint16_t block, const char *data, size_t n) {
    memset(buffer, 0, *length);
    *length = 0;
    *(buffer) = DATA;
    *length += sizeof(uint16_t);
    *(buffer + *length) = block;
    *length += sizeof(uint16_t);
    memcpy(buffer + *length, data, n);
    *length += n;

    return 0;
}

Эта функция заполнения buffer с содержимым пакета и заполнить length с размером пакета. Это работает нормально, если block ниже 128. Если он больше 128, он становится -128.

Вы можете мне помочь?

1 ответ

Решение

Если что-то не имеет размер в один байт, вы не можете назначить его *buffer, Оба эти назначения неверны:

*(buffer) = DATA;
*(buffer + *length) = block;

Когда ты пишешь uint16_tиспользовать memcpy:

uint16_t dataToWrite = ...;
memcpy(buffer + *length, &dataToWrite, sizeof(uint16_t));

Вы еще не закончили, потому что вам нужно решить, что назначить dataToWrite, Если вы делаете это

uint16_t dataToWrite = block;

данные, передаваемые по проводам, будут в аппаратном порядке, что никогда не должно происходить. Вместо этого вам нужно использовать один из hton Семейные функции для преобразования вашего номера в сетевой формат:

uint16_t dataToWrite = htons(block);

Я проверяю это на той же машине, только с

printf("block : %d\n", packet[sizeof(uint_16)]);

Это неверно по той же причине, что и назначение: packet[sizeof(uint_16)] делает int или же unsigned int от char/uint8_t значение хранится в позиции sizeof(uint_16)и он также игнорирует другой байт.

Чтобы исправить это вам нужно использовать memcpy снова. Конечно, если вы использовали htons на стороне записи, вы должны использовать ntohs перед печатью:

uint16_t dataToPrint;
memcpy(dataToPrint, &packet[sizeof(uint16_t)], sizeof(uint16_t));
dataToPrint = ntohs(dataToPrint);
printf("block : %u\n", dataToPrint);
Другие вопросы по тегам