Опубликован: 16.09.2004 | Уровень: специалист | Доступ: свободно | ВУЗ: Московский физико-технический институт
Лекция 10:

Семейство протоколов TCP/IP. Сокеты (sockets) в UNIX и основы работы с ними

< Лекция 9 || Лекция 10: 1234567891011

Сетевой порядок байт. Функции htons(), htonl(), ntohs(), ntohl()

Передача от одного вычислительного комплекса к другому символьной информации, как правило (когда один символ занимает один байт), не вызывает проблем. Однако для числовой информации ситуация усложняется.

Схема взаимодействия клиента и сервера для протокола UDP

Рис. 15-16.6. Схема взаимодействия клиента и сервера для протокола UDP

Как известно, порядок байт в целых числах, представление которых занимает более одного байта, может быть для различных компьютеров неодинаковым. Есть вычислительные системы, в которых старший байт числа имеет меньший адрес, чем младший байт (big-endian byte order), а есть вычислительные системы, в которых старший байт числа имеет больший адрес, чем младший байт (little-endian byte order). При передаче целой числовой информации от машины, имеющей один порядок байт, к машине с другим порядком байт мы можем неправильно истолковать принятую информацию. Для того чтобы этого не произошло, было введено понятие сетевого порядка байт, т.е. порядка байт, в котором должна представляться целая числовая информация в процессе передачи ее по сети (на самом деле – это big-endian byte order). Целые числовые данные из представления, принятого на компьютере-отправителе, переводятся пользовательским процессом в сетевой порядок байт, в таком виде путешествуют по сети и переводятся в нужный порядок байт на машине-получателе процессом, которому они предназначены. Для перевода целых чисел из машинного представления в сетевое и обратно используется четыре функции: htons() , htonl() , ntohs() , ntohl() .

Функции преобразования порядка байт

Прототипы функций

#include <netinet/in.h>
unsigned long int htonl(
    unsigned long int hostlong);
unsigned short int htons(
    unsigned short int hostshort);
unsigned long int ntohl(
    unsigned long int netlong);
unsigned short int ntohs(
    unsigned short int netshort);

Описание функций

Функция htonl осуществляет перевод целого длинного числа из порядка байт, принятого на компьютере, в сетевой порядок байт.

Функция htons осуществляет перевод целого короткого числа из порядка байт, принятого на компьютере, в сетевой порядок байт.

Функция ntohl осуществляет перевод целого длинного числа из сетевого порядка байт в порядок байт, принятый на компьютере.

Функция ntohs осуществляет перевод целого короткого числа из сетевого порядка байт в порядок байт, принятый на компьютере.

В архитектуре компьютеров i80x86 принят порядок байт, при котором младшие байты целого числа имеют младшие адреса. При сетевом порядке байт, принятом в Internet, младшие адреса имеют старшие байты числа.

Параметр у них – значение, которое мы собираемся конвертировать. Возвращаемое значение – то, что получается в результате конвертации. Направление конвертации определяется порядком букв h (host) и n (network) в названии функции, размер числа – последней буквой названия, то есть htons – это host to network short, ntohl network to host long.

Для чисел с плавающей точкой все обстоит гораздо хуже. На разных машинах могут различаться не только порядок байт, но и форма представления такого числа. Простых функций для их корректной передачи по сети не существует. Если требуется обмениваться действительными данными, то либо это нужно делать на гомогенной сети, состоящей из одинаковых компьютеров, либо использовать символьные и целые данные для передачи действительных значений.

Функции преобразования IP-адресов inet_ntoa(), inet_aton()

Нам также понадобятся функции, осуществляющие перевод IP-адресов из символьного представления (в виде четверки чисел, разделенных точками) в числовое представление и обратно. Функция inet_aton() переводит символьный IP-адрес в числовое представление в сетевом порядке байт.

Функция возвращает 1, если в символьном виде записан правильный IP-адрес, и 0 в противном случае – для большинства системных вызовов и функций это нетипичная ситуация. Обратите внимание на использование указателя на структуру struct in_addr в качестве одного из параметров данной функции. Эта структура используется для хранения IP-адресов в сетевом порядке байт. То, что используется структура, состоящая из одной переменной, а не сама 32-битовая переменная, сложилось исторически, и авторы в этом не виноваты.

Для обратного преобразования применяется функция inet_ntoa() .

Функции преобразования IP-адресов

Прототипы функций

#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int inet_aton(const char *strptr, 
    struct in_addr *addrptr);
char *inet_ntoa(struct in_addr *addrptr);

Описание функций

Функция inet_aton переводит символьный IP-адрес, расположенный по указателю strptr, в числовое представление в сетевом порядке байт и заносит его в структуру, расположенную по адресу addrptr. Функция возвращает значение 1, если в строке записан правильный IP-адрес, и значение 0 в противном случае. Структура типа struct in_addr используется для хранения IP-адресов в сетевом порядке байт и выглядит так:

struct in_addr {
    in_addr_t s_addr; 
};

То, что используется адрес такой структуры, а не просто адрес переменной типа in_addr_t, сложилось исторически.

Функция inet_ntoa применяется для обратного преобразования. Числовое представление адреса в сетевом порядке байт должно быть занесено в структуру типа struct in_addr, адрес которой addrptr передается функции как аргумент. Функция возвращает указатель на строку, содержащую символьное представление адреса. Эта строка располагается в статическом буфере, при последующих вызовах ее новое содержимое заменяет старое содержимое.

Функция bzero()

Функция 2 настолько проста, что про нее нечего рассказывать. Все видно из описания.

Функция bzero

Прототип функции

#include <string.h>
void bzero(void *addr, int n);

Описание функции

Функция bzero заполняет первые n байт, начиная с адреса addr, нулевыми значениями. Функция ничего не возвращает.

Теперь мы можем перейти к системным вызовам, образующим интерфейс между пользовательским уровнем стека протоколов TCP/IP и транспортным протоколом UDP.

< Лекция 9 || Лекция 10: 1234567891011
лия логовина
лия логовина

организовать двустороннюю поочередную связь процесса-родителя и процесса-ребенка через pipe, используя для синхронизации сигналы sigusr1 и sigusr2.

Макар Оганесов
Макар Оганесов