UNIX: разработка сетевых приложений
#include <strings.h>void bzero(void *<i>dest</i>, size_t <i>nbytes</i>);void bcopy(const void *<i>src</i>, void *<i>dest</i>, size_t <i>nbytes</i>);int bcmp(const void *<i>ptr1</i>, const void *<i>ptr2</i>, size_t <i>nbytes</i>);<i>Возвращает: 0 в случае равенства, ненулевое значение в случае неравенства</i>ПРИМЕЧАНИЕМы впервые встречаемся со спецификатором const. В приведенном примере он служит признаком того, что значения, на которые указывает указатель, то есть src, ptr1 и ptr2, не изменяются функцией. Другими словами, область памяти, на которую указывает указатель со спецификатором const, считывается функцией, но не изменяется.
Функция
обнуляет заданное число байтов в указанной области памяти. Мы часто используем эту функцию для инициализации структуры адреса сокета нулевым значением. Функцияbzeroкопирует заданное число байтов из источника в место назначения. Функцияbcopyсравнивает две произвольных последовательности байтов и возвращает нулевое значение, если две байтовых строки идентичны, и ненулевое — в противном случае.bcmpСледующие функции являются функциями ANSI С:
#include <string.h>void *memset(void *<i>dest</i>, int <i>c</i>, size_t <i>len</i>);void *memcpy(void *<i>dest</i>, const void *<i>src</i>, size_t <i>nbytes</i>);int memcmp(const void *<i>ptr1</i>, const void *<i>ptr2</i>, size_t <i>nbytes</i>);<i>Возвращает: 0 в случае равенства, значение <0 или >0 в случае неравенства (см. текст)</i>Функция
присваивает заданному числу байтов значение с. Функцияmemsetаналогична функцииmemcpy, но имеет другой порядок двух аргументов. Функцияbcopyкорректно обрабатывает перекрывающиеся поля, в то время как поведение функцииbcopyне определено, если источник и место назначения перекрываются. В случае перекрывания полей должна использоваться функция ANSI Сmemcpy(упражнение 30.3).memmoveПРИМЕЧАНИЕЧтобы запомнить порядок аргументов функции memcpy, подумайте о том, что он совпадает с порядком аргументов в операторе присваивания (справа — оригинал, слева — копия).
dest = src;Последним аргументом этой функции (как и всех ANSI-функций memXXX) всегда является длина области памяти.
Функция
сравнивает две произвольных последовательности байтов и возвращает нуль, если они идентичны. В противном случае знак возвращаемого значения определяется знаком разности между первыми несовпадающими байтами, на которые указывают ptr1 и ptr2. Предполагается, что сравниваемые байты принадлежат к типуmemcmp.unsigned char3.6. Функции inet_aton, inet_addr и inet_ntoa
Существует две группы функций преобразования адресов, которые мы рассматриваем в этом и следующем разделах. Они выполняют преобразование адресов Интернета из строк ASCII (удобных для человеческого восприятия) в двоичные значения с сетевым порядком байтов (эти значения хранятся в структурах адресов сокетов).
1. Функции
,inet_atonиinet_ntoaпреобразуют адрес IPv4 из точечно-десятичной записи (например, 206.168.112.96) в 32-разрядное двоичное значение в сетевом порядке байтов. Возможно, вы встретите эти функции в многочисленных существующих программах.inet_addr2. Более новые функции
иinet_ptonработают и с адресами IPv4, и с адресами IPv6. Эти функции, описываемые в следующем разделе, мы используем в книге.inet_ntop#include <arpa/inet.h>int inet_aton(const char *<i>strptr</i>, struct in_addr *<i>addrptr</i>);<i>Возвращает: 1, если строка преобразована успешно, 0 в случае ошибки</i>in_addr_t inet_addr(const char *<i>strptr</i>);<i>Возвращает: 32-разрядный адрес IPv4 в сетевом порядке байтов: INADDR_NONE в случае ошибки</i>char *inet_ntoa(struct in_addr <i>inaddr</i>);<i>Возвращает: указатель на строку с адресом в точечно-десятичной записи</i>Первая из названных функций,
, преобразует строку, на которую указываетinet_aton, в 32-разрядное двоичное число, записанное в сетевом порядке байтов, передаваемое через указательstrptr. При успешном выполнении возвращаемое значение равно 1, иначе возвращается нуль.addrptrПРИМЕЧАНИЕФункция inet_aton обладает одним недокументированным свойством: если addrptr — пустой указатель (null pointer), функция все равно выполняет проверку допустимости адреса, содержащегося во входной строке, но не сохраняет результата.
Функция
выполняет то же преобразование, возвращая в качестве значения 32-разрядное двоичное число в сетевом порядке байтов. Проблема при использовании этой функции состоит в том, что все 232 возможных двоичных значений являются действительными IP-адресами (от 0.0.0.0 до 255.255.255.255), но в случае возникновения ошибки функция возвращает константуinet_addr(обычно представленную двоичным числом, состоящим из 32 бит, установленных в единицу). Это означает, что точечно-десятичная запись 255.255.255.255 (ограниченный адрес для широковещательной передачи IPv4, см. раздел 18.2) не может быть обработана этой функцией, поскольку ее двоичное значение выглядит как указание на сбой при выполнении функции.INADDR_NONEПРИМЕЧАНИЕХарактерной проблемой, сопровождающей выполнение функции inet_addr, может стать то, что, как утверждается в некоторых руководствах, в случае ошибки она возвращает значение -1 вместо INADDR_NONE. С некоторыми компиляторами это может вызвать проблемы при сравнении возвращаемого значения функции (значение без знака) с отрицательной константой.