Категории
Самые читаемые
ChitatKnigi.com » 🟢Компьютеры и Интернет » Интернет » Основы программирования в Linux - Мэтью Нейл

Основы программирования в Linux - Мэтью Нейл

Читать онлайн Основы программирования в Linux - Мэтью Нейл
1 ... 265 266 267 268 269 270 271 272 273 ... 324
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать

Для того чтобы компьютеры разных типов могли согласовать значения многобайтовых целых чисел, передаваемых по сети, необходимо определить сетевой порядок передачи байтов. Перед передачей данных клиентские и серверные программы должны преобразовать собственное внутреннее представление целых чисел в соответствии с принятым в сети порядком следования байтов. Делается это с помощью функций, определенных в заголовочном файле netinet/in.h. К ним относятся следующие:

<b>#include &lt;netinet/in.h&gt;</b>

<b>unsigned long int htonl(unsigned long int hostlong);</b>

<b>unsigned short int htons(unsigned short int hostshort);</b>

<b>unsigned long int ntohl(unsigned long int netlong);</b>

<b>unsigned short int ntohs(unsigned short int netshort);</b>

Эти функции преобразуют 16- и 32-разрядные целые из внутреннего формата в сетевой порядок следования байтов и обратно. Их имена соответствуют сокращенному названию выполняемых преобразований, например "host to network, long" (htonl, компьютерный в сетевой, длинные целые) и "host to network, short" (htons, компьютерный в сетевой, короткие целые). Компьютерам, у которых порядок следования байтов соответствует сетевому, эти функции предоставляют пустые операции.

Для обеспечения корректного порядка следования при передаче 16-разрядного целого числа ваши сервер и клиент должны применить эти функции к адресу порта. В программу server3.c следует внести следующие изменения:

<i>server_address.sin_addr_s_addr = htonl(INADDR_ANY);</i>

<i>server_address.sin_port = htons(9734);</i>

Результат, возвращаемый функцией inet_addr(&quot;127.0.0.1&quot;), преобразовывать не нужно, потому что в соответствии со своим определением она возвращает результат с сетевым порядком следования байтов. В программу client3.c необходимо внести следующее изменение:

<i>address.sin_port = htons(9734);</i>

В сервер, благодаря применению константы INADDR_ANY, внесено изменение, позволяющее принимать запросы на соединение от любых IP-адресов.

Теперь, выполнив программы server3 и client3, вы увидите корректный номер порта, используемый для локального соединения:

$ <b>netstat</b>

Active Internet connections

Proto Recv-Q Send-Q Local Address  Foreign Address (State)   User

tcp        1      0 localhost:9734 localhost:1175  TIME_WAIT root

Примечание

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

Сетевая информация

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

Если у вас есть на это право, можно добавить свой сервер к списку известных сервисов в файл /etc/services, который назначает имена номерам портов, так что клиенты могут использовать вместо номеров символические имена сервисов.

Точно так же зная имя компьютера, можно определить IP-адрес, вызвав функции базы данных сетевых узлов (host database), которые найдут эти адреса. Делают они это, обращаясь за справкой к конфигурационным файлам, например, etc/hosts или к сетевым информационным сервисам, таким как NIS (Network Information Services (сервисы сетевой информации), ранее известным как Yellow Pages (желтые страницы)) и DNS (Domain Name Service, служба доменных имен).

Функции базы данных сетевых узлов или хостов (Host database) объявлены в заголовочном файле интерфейса netdb.h:

<b>#include &lt;netdb.h&gt;</b>

<b>struct hostent *gethostbyaddr(const void* addr, size_t len, int type);</b>

<b>struct hostent* gethostbyname(const char* name);</b>

Структура, возвращаемая этими функциями, должна как минимум содержать следующие элементы.

<b>struct hostent {</b>

<b> char *h_name;      /* Имя узла */</b>

<b> char **h_aliases;  /* Перечень псевдонимов (nicknames) */</b>

<b> int h_addrtype;    /* Тип адреса */</b>

<b> int h_length;      /* Длина адреса в байтах */</b>

<b> char **h_addr_list /* Перечень адреса (сетевой порядок байтов) */</b>

<b>};</b>

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

Аналогично информацию, касающуюся сервисов и связанных номеров портов, можно получить с помощью информационных функций сервисов:

<b>#include &lt;netdb.h&gt;</b>

<b>struct servent *getservbyname(const char *name, const char *proto);</b>

<b>struct servent *getservbyport(int port, const char *proto);</b>

Параметр proto задает протокол, который будет применяться для подключения к сервису, либо "tcp" для TCP-соединений типа SOCK_STREAM, либо "udp" для UDP-дейтаграмм типа SOCK_DGRAM.

Структура servent содержит как минимум следующие элементы:

<b>struct servent {</b>

<b> char *s_name;     /* Имя сервиса */</b>

<b> char **s_aliases; /* Список псевдонимов (дополнительных имен) */</b>

<b> int s_port;       /* Номер IP-порта */</b>

<b> char *s_proto;    /* Тип сервиса, обычно &quot;tcp&quot; или &quot;udp&quot; */</b>

<b>}</b>

Вы можете собрать воедино информацию о компьютере из базы данных сетевых узлов, вызвав функцию gethostbyname и выведя ее результаты. Учтите, что адрес необходимо преобразовать в соответствующий тип и перейти от сетевого упорядочивания к пригодной для вывода строке с помощью преобразования inet_ntoa, определенного следующим образом:

<b>#include &lt;arpa/inet.h&gt;</b>

<b>char *inet_ntoa(struct in_addr in);</b>

1 ... 265 266 267 268 269 270 271 272 273 ... 324
Перейти на страницу:
Открыть боковую панель
Комментарии
Жанна
Жанна 27.07.2025 - 01:48
Люблю настоящих мужчин. Главный герой, именно такой.
Майя
Майя 25.07.2025 - 01:56
Благодарю за рассказ. Не растянуто и очень интересно
Руслана
Руслана 17.06.2025 - 12:59
Замечательные рекомендации по подбору персонала 👏
Елизавета
Елизавета 16.05.2025 - 16:36
Осилила только первую страницу, как можно вообще такую муть писать, не видела, случайно, в лифте, не узнала своего босса. Это же детский сад. Все как под копирку, еще застряли в лифте, случайно не