При передаче числовых значений через Интернет необходимо учитывать две вещи.
Первый - это порядок байтов, порядок, в котором появляются байты (или иногда биты). Предположим, у вас есть 32-битное значение 0xAABBCCDD. Процессоры Intel представляют собой машины с прямым порядком байтов, что означает, что эти байты будут храниться как {0xDD, 0xCC, 0xBB, 0xAA}. Другими словами, младший байт сохраняется по младшему адресу. В машине с прямым порядком байтов байты будут храниться как {0xAA, 0xBB, 0xCC, 0xDD}, причем младший байт будет иметь самый высокий адрес.
При передаче многобайтовых целых чисел между двумя компьютерами необходимо убедиться, что они оба правильно интерпретируют данные друг друга, даже если у них разные порядки байтов. К счастью, существует стандарт, называемый Сетевой порядок байтов, который является прямым порядком байтов, и есть 4 полезные функции для преобразования между порядком хоста и порядком сети:
ntohl (сеть к хосту, длинная)
ntohs (сеть к хосту, короткая запись)
htonl (хост в сеть, длинный)
htons (хост в сеть, короткий)
Длинные версии работают с 32-разрядными целыми числами и короткие версии с 16-разрядными целыми числами. Пока вы всегда вызываете * hton ** перед передачей данных по сети и вызываете * ntoh ** при чтении из сети, данные будут в правильном порядке байтов.
Конечно, самый простой способ обойти эту проблему, особенно если у вас есть только 20 команд, это просто использовать одиночные байты или char s.
Вторая проблема, с которой вам приходится сталкиваться, - это кодирование. Как представлены целые числа со знаком? Используя знак-бит? Два дополнения? Опять же, вы сталкиваетесь с проблемами, когда разные платформы в сети используют разные представления. Если вы придерживаетесь неподписанных типов, у вас действительно не должно быть проблем.
То, что вы используете для представления своих команд в вашей программе, полностью зависит от вас. Просто убедитесь, что вы правильно определили свой протокол и соблюдаете его при передаче и чтении данных.
Например:
enum command_t { one, two, three }
void send_command(command_t c) {
send((unsigned char)c);
}
command_t read_command() {
return (command_t)recv();
}
void send(unsigned char c) { ... }
unsigned char recv() { ... }