2016-04-09 3 views
1

Для школьного проекта, я должен разработать сервер TFTP в C. я должен построить пакет в массиве полукокса, как это:uint16_t в массиве полукокса

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.

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

+0

'* (буфер + * длина) = блок;' - вы назначая 'uint16_t' к' char' (который, по-видимому, «подписан» на вашей платформе, как и большинство других). Может захотеть переосмыслить это. – WhozCraig

+0

Я использовал массив uint8_t и, похоже, работает. Спасибо :) – Mathieu

ответ

3

Если какой-то размер не равен одному байту, вы не можете назначить его *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-family functions для преобразования номера в формат сети:

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); 
+0

Это не работает для меня. Возможно, это потому, что я использую массив char (который подписан)? Когда я использую массив uint8_t, он работает :) – Mathieu

+0

Хит введите при наборе :) – Mathieu

+1

@Mathieu Пока неясно, что конкретно не работает. – dasblinkenlight

Смежные вопросы