Типирование char для типа int (для сокета) - PullRequest
0 голосов
/ 29 июля 2011

Я, вероятно, задавал этот вопрос дважды с того дня, но я до сих пор не получил положительного ответа. Моя проблема в том, что у меня есть IP-адрес, который хранится в unsigned char. Теперь я хочу отправить этот IP-адрес через сокет от клиента к серверу. Люди посоветовали мне использовать htonl() и ntohl() для передачи сетевых байтов, но я не могу понять, что аргументы для htonl() и ntohl() являются целыми числами ... как я могу использовать его в случае unsigned char ?? если я не могу его использовать, как я могу убедиться, что если я отправлю 130.191.166.230 в моем буфере, получатель будет получать одно и то же постоянно? Любые материалы или рекомендации будут оценены. Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 29 июля 2011

Если у вас есть строка без знака char array (вдоль линий "10.0.0.7"), формирующая IP-адрес (и я предполагаю, что вы это делаете, поскольку 32-битных char систем очень мало вокруг, что делает довольно сложным сохранение IP-адреса в один символ), вы можете просто отправить его как есть и позволить другому концу использовать его (при условии, что вы, конечно, оба кодируете символы одинаково, например, в ASCII) .


С другой стороны, у вас может быть четырехбайтовый массив символов (предполагая, что символы - это восемь битов), содержащий двоичный IP-адрес.

Использование htonl и ntohl должно гарантировать, что эти двоичные данные отправляются в порядке, понятном как для систем с прямым порядком байтов, так и для систем с прямым порядком байтов.

С этой целью сетевой порядок байтов (порядок байтов "на проводе") имеет порядок с прямым порядком байтов, поэтому эти функции в основном не делают ничего с системами с прямым порядком байтов. В системах с прямым порядком байтов они обмениваются байтами.

Другими словами, у вас могут быть следующие двоичные данные:

uint32_t ipaddress = 0x0a010203; // for 10.1.2.3

В макете с прямым порядком байтов, который будет храниться как 0x0a,0x01,0x02,0x03, в формате с прямым порядком байтов как 0x03,0x02,0x01,0x0a.

Итак, если вы хотите отправить его в порядке сетевых байтов (что любая система с прямым порядком байтов сможет понять), вы не можете просто сделать:

write (fd, &ipaddress, 4);

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

Что вам нужно сделать, это:

uint32_t ipaddress = 0x0a010203; // for 10.1.2.3
uint32_t ip_netorder = htonl (ipaddress); // change if necessary.
write (fd, &ip_netorder, 4);

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

На самом деле, эта схема может обрабатывать больше, чем просто порядковый номер. Если у вас есть схема 32-битного целочисленного кодирования, где ABCD (четыре байта) кодируются как A,D,B,C или даже там, где у вас есть странно дикая битовая смесь, формирующая ваши целые числа (например, используя сначала четные биты, а затем нечетные биты), это будет все еще работает, поскольку ваши локальные htonl и ntohl знают об этих форматах и ​​могут правильно преобразовать их в сетевой порядок байтов.

0 голосов
/ 29 июля 2011

IP4-адрес составляет 4 байта (он же символ). Таким образом, у вас будет 4 неподписанных символа в массиве. приведите этот массив для отправки через него.

например. беззнаковый IP-адрес [4];

использовать ((char *) IP) в качестве буфера данных для отправки и отправлять 4 байта из него.

0 голосов
/ 29 июля 2011

Массив символов имеет определенный порядок и не зависит от порядкового номера - они всегда работают от низкого до высокого адреса по соглашению.

У вас есть строка или 4 байта?

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