if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
break; /* Успех */
/* Сбой в вызове bind(): закрываем этот сокет и пробуем следующий адрес */
close(sfd);
}
if (rp!= NULL && doListen) {
if (listen(sfd, backlog) == -1) {
freeaddrinfo(result);
return -1;
}
}
if (rp!= NULL && addrlen!= NULL)
*addrlen = rp->ai_addrlen;
/* Возвращаем размер структуры с адресом */
freeaddrinfo(result);
return (rp == NULL)? — 1: sfd;
}
int
inetListen(const char *service, int backlog, socklen_t *addrlen)
{
return inetPassiveSocket(service, SOCK_STREAM, addrlen, TRUE, backlog);
}
int
inetBind(const char *service, int type, socklen_t *addrlen)
{
return inetPassiveSocket(service, type, addrlen, FALSE, 0);
}
char *
inetAddressStr(const struct sockaddr *addr, socklen_t addrlen,
char *addrStr, int addrStrLen)
{
char host[NI_MAXHOST], service[NI_MAXSERV];
if (getnameinfo(addr, addrlen, host, NI_MAXHOST,
service, NI_MAXSERV, NI_NUMERICSERV) == 0)
snprintf(addrStr, addrStrLen, "(%s, %s)", host, service);
else
snprintf(addrStr, addrStrLen, "(?UNKNOWN?)");
addrStr[addrStrLen — 1] = '\0'; /* Не забываем добавить нулевой символ в конце */
return addrStr;
}
sockets/inet_sockets.c
При написании приложений, которые взаимодействуют по сети, использование сокетов интернет-домена является обязательным. Но если наши приложения находятся на одном и том же компьютере, то можно применять сокеты как в интернет-, так и в UNIX-домене. Так какой же домен лучше выбрать в таком случае и чем при этом следует руководствоваться?
Применение сокетов интернет-домена обычно является наиболее простым вариантом, потому что это позволяет запускать программы как локально, так и на разных узлах сети. Однако существует несколько причин, которые могут склонить нас к выбору UNIX-домена.
• В ряде систем сокеты UNIX-домена работают быстрее, чем сокеты интернет-домена.
• Для управления доступом к сокетам UNIX-домена можно применять права доступа к каталогу (и к файлу, если речь идет о Linux). Таким образом можно позволить подключаться к слушающему сокету или отправлять датаграммы только приложениям, которые имеют заданного владельца или входят в определенную группу. Так мы получаем простой механизм аутентификации клиентов. В интернет-домене для организации чего-то подобного требуются дополнительные действия.
• При использовании сокетов UNIX-домена мы передаем дескрипторы открытых файлов и учетные данные отправителя (см. подраздел 57.13.3).
Существует множество печатных и электронных ресурсов, посвященных TCP/IP и программным интерфейсам сокетов.
• [Stevens at al., 2004] — ключевая книга по сетевому программированию с помощью программного интерфейса сокетов. [Snader, 2000] содержит дополнительные полезные руководства на данную тему.
• [Stevens, 1994] и [Wright & Stevens, 1995] описывают стек TCP/IP в подробностях. [Comer, 2000], [Comer & Stevens, 1999], [Comer & Stevens, 2000], [Kozierok, 2005] и [Goralski, 2009] этот материал тоже хорошо освещен.
• [Tanenbaum, 2002] содержит общие сведения об истории компьютерных сетей.
• [Herbert, 2004] подробно описывает стек TCP/IP в Linux 2.6.
• Руководство GNU языка C (находится на http://www.gnu.org/) содержит обширную информацию о программном интерфейсе сокетов.
• На сайте IBM Redbook находится документ под названием TCP/IP Tutorial and Technical Overview, в котором подробно описаны основные понятия, относящиеся к сетям, внутренности TCP/IP, программный интерфейс сокетов и множество связанных с этим тем. Документ доступен для свободной загрузки на http://www.redbooks.ibm.com/.
• [Gont, 2008] и [Gont, 2009 (b)] рассматривают протоколы IPv4 и TCP с точки зрения безопасности.
• Новостная рассылка comp.protocols.tcp-ip посвящена вопросам, связанным с сетевыми протоколами семейства TCP/IP.
• В книге [Sarolahti & Kuznetsov, 2002] описывается управление перегрузкой и другие нюансы реализации TCP в Linux.
• Информацию, относящуюся в первую очередь к Linux, можно найти на следующих страницах руководства: socket(7), ip(7), raw(7), tcp(7), udp(7) и packet(7).
• См. также списки RFC-документов в разделе 54.7.
Сокеты интернет-домена позволяют приложениям, находящимся на разных компьютерах, взаимодействовать друг с другом по сети TCP/IP. Адреса этих сокетов включают в себя IP-адрес и номер порта. В IPv4 числовые адреса занимают 32 бита, а в IPv6 — 128 бит. Датаграммные сокеты интернет-домена работают по протоколу UDP и предоставляют ненадежный канал взаимодействия, ориентированный на обмен сообщениями и не поддерживающий соединения. Потоковые сокеты интернет-домена работают по протоколу TCP; они обеспечивают надежный, двунаправленный, основанный на байтовом потоке канал обмена данными между двумя приложениями, соединенными друг с другом.