Изменение определенного байта в потоке пакетов - PullRequest
0 голосов
/ 23 сентября 2010

Я использую C для реализации потока пакетов, который будет отправлен по беспроводной сети, и застрял в следующей проблеме. У меня есть целые 2 байта без знака, в следующем формате в двоичном формате: XXXX YYYY XXXX XXXX, где X & Y - биты.

Глядя на формат выше, мне нужно просто изменить биты YYYY и оставить остальные биты в структуре пакета.

Я пробовал сдвигать биты и маскировать, но, похоже, ничего не работает.

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

Любая помощь или руководство в правильном направлении было бы здорово.

Спасибо!

Ответы [ 3 ]

6 голосов
/ 23 сентября 2010

Допустим, вы хотите заменить биты YYYY на ZZZZ.

Сначала вам нужно очистить биты YYYY в исходном значении.Это можно сделать с помощью:

oldvalue & 0xF0FF

, что дает вам XXXX 0000 XXXX XXXX.

Далее вам нужно взять новые биты ZZZZ и сдвинуть их влево, с помощью:

z << 8

, который дает 0000 ZZZZ 0000 0000.

Наконец, вам нужно объединить два значения, используя оператор или:

(oldvalue & 0xF0FF) | (z << 8)

, который дает вам XXXX ZZZZ XXXX XXXX.

0 голосов
/ 24 сентября 2010

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

Семейство функций hton и ntoh переключается на и от имени хоста и сети (big endian). Посмотрите htons, ntohs, htonl и ntohl для получения дополнительной информации. Эти функции на самом деле ничего не делают, если на главном компьютере есть порядок байтов, но многие (например, x86) имеют порядок байтов. На компьютере с прямым порядком байтов htons (0x1234) приведет к 0x3412, потому что это меняет местами байты.

Так как я не знаю, как выглядит поток вашей программы, вот моя лучшая попытка наглядного примера.

uint16_t set_those_bits(uint16_t x) {
    uint16_t mask = htons(0x0F00);
    return x | mask;
}

Эта функция не изменяет порядковый номер данных, передаваемых относительно возвращаемого значения, но предполагает, что значение является порядковым номером сети, поэтому меняет порядковый номер маски с порядкового номера узла на сеть, а затем устанавливает эти биты в результате.

uint16_t clear_those_bits(uint16_t x) {
    uint16_t mask = htons(0xF0FF);
    return x & mask;
}

uint16_t toggle_those_bits(uint16_t x) {
    uint16_t mask = htons(0x0f00);
    return x ^ mask;
}
0 голосов
/ 23 сентября 2010

value = (value & 0xF0FF) | (newY << 8); или его близкий вариант, в зависимости от порядка байтов?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...