Эти функции преобразуют 16- и 32-разрядные целые из внутреннего формата в сетевой порядок следования байтов и обратно. Их имена соответствуют сокращенному названию выполняемых преобразований, например "host to network, long" (htonl, компьютерный в сетевой, длинные целые) и "host to network, short" (htons, компьютерный в сетевой, короткие целые). Компьютерам, у которых порядок следования байтов соответствует сетевому, эти функции предоставляют пустые операции.
Для обеспечения корректного порядка следования при передаче 16-разрядного целого числа ваши сервер и клиент должны применить эти функции к адресу порта. В программу server3.c следует внести следующие изменения:
Результат, возвращаемый функцией inet_addr("127.0.0.1")
, преобразовывать не нужно, потому что в соответствии со своим определением она возвращает результат с сетевым порядком следования байтов. В программу client3.c необходимо внести следующее изменение:
В сервер, благодаря применению константы INADDR_ANY
, внесено изменение, позволяющее принимать запросы на соединение от любых IP-адресов.
Теперь, выполнив программы server3 и client3, вы увидите корректный номер порта, используемый для локального соединения:
$ netstat
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:
#include
struct hostent *gethostbyaddr(const void* addr, size_t len, int type);
struct hostent* gethostbyname(const char* name);
Структура, возвращаемая этими функциями, должна как минимум содержать следующие элементы.
struct hostent {
char *h_name; /* Имя узла */
char **h_aliases; /* Перечень псевдонимов (nicknames) */
int h_addrtype; /* Тип адреса */
int h_length; /* Длина адреса в байтах */
char **h_addr_list /* Перечень адреса (сетевой порядок байтов) */
};
Если в базе данных нет элемента, соответствующего заданному узлу или адресу, информационные функции вернут пустой указатель.
Аналогично информацию, касающуюся сервисов и связанных номеров портов, можно получить с помощью информационных функций сервисов:
#include
struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);