розетки Беркли

API межпроцессного взаимодействия

Сокет Berkeley ( BSD ) — это интерфейс прикладного программирования (API) для сокетов домена Интернета и сокетов домена Unix , используемый для межпроцессного взаимодействия (IPC). Обычно он реализуется как библиотека подключаемых модулей. Он появился в операционной системе Unix 4.2BSD , выпущенной в 1983 году.

Сокет — это абстрактное представление ( дескриптор ) локальной конечной точки сетевого пути связи. API сокетов Беркли представляет его как файловый дескриптор в философии Unix , который предоставляет общий интерфейс для ввода и вывода в потоки данных.

Сокеты Berkeley с небольшими изменениями превратились из фактического стандарта в компонент спецификации POSIX . Термин сокеты POSIX по сути является синонимом сокетов Berkeley , но их также называют сокетами BSD , что подтверждает первую реализацию в Berkeley Software Distribution .

История и внедрения

Сокеты Беркли появились в операционной системе 4.2BSD Unix , выпущенной в 1983 году, как программный интерфейс. Однако только в 1989 году Калифорнийский университет в Беркли смог выпустить версии операционной системы и сетевой библиотеки, свободные от лицензионных ограничений проприетарного Unix корпорации AT&T .

Все современные операционные системы реализуют версию интерфейса сокета Беркли. Он стал стандартным интерфейсом для приложений, работающих в Интернете . Даже реализация Winsock для MS Windows, созданная независимыми разработчиками, точно следует стандарту.

API сокетов BSD написано на языке программирования C. Большинство других языков программирования предоставляют похожие интерфейсы, обычно написанные как библиотека-обертка на основе API C. [1]

Сокеты BSD и POSIX

По мере того, как сокетный API Беркли развивался и в конечном итоге привел к сокетному API POSIX, [2] некоторые функции были объявлены устаревшими или удалены и заменены другими. POSIX API также разработан для повторного входа и поддерживает IPv6.

ДействиеБСДPOSIX
Преобразование текстового адреса в упакованный адресинет_атонинет_птон
Преобразование из упакованного адреса в текстовый адресинет_нтоаинет_нтоп
Прямой поиск имени хоста/службыgethostbyname, gethostbyaddr, getservbyname, getservbyportgetaddrinfo
Обратный поиск имени хоста/службыgethostbyaddr, getservbyportgetnameinfo

Альтернативы

API интерфейса транспортного уровня (TLI) на основе STREAMS предлагает альтернативу API сокета. Многие системы, которые предоставляют API TLI, также предоставляют API сокета Беркли.

Системы, отличные от Unix, часто предоставляют API сокетов Беркли с уровнем трансляции для собственного сетевого API. Plan 9 [3] и Genode [4] используют API файловой системы с управляющими файлами, а не дескрипторами файлов.

Заголовочные файлы

Интерфейс сокета Berkeley определен в нескольких файлах заголовков. Имена и содержимое этих файлов немного различаются в зависимости от реализации. В общем, они включают:

ФайлОписание
sys/сокет.hОсновные функции сокетов и структуры данных.
netinet/in.hСемейства адресов AF_INET и AF_INET6 и соответствующие им семейства протоколов PF_INET и PF_INET6. Они включают стандартные IP-адреса и номера портов TCP и UDP.
sys/un.hСемейство адресов PF_UNIX и PF_LOCAL. Используется для локальной связи между программами, работающими на одном компьютере.
arpa/inet.hФункции для манипулирования числовыми IP-адресами.
netdb.hФункции для перевода имен протоколов и имен хостов в числовые адреса. Поиск локальных данных, а также служб имен.

Функции API сокета

Блок-схема клиент-серверной транзакции с использованием сокетов с протоколом управления передачей (TCP).

API сокетов Беркли обычно предоставляет следующие функции:

  • socket() создает новый сокет определенного типа, идентифицируемый целым числом, и выделяет ему системные ресурсы.
  • bind() обычно используется на стороне сервера и связывает сокет со структурой адреса сокета, т. е. указанным локальным IP-адресом и номером порта.
  • listen() используется на стороне сервера и переводит связанный TCP-сокет в состояние прослушивания.
  • connect() используется на стороне клиента и назначает свободный номер локального порта сокету. В случае сокета TCP, это вызывает попытку установить новое соединение TCP.
  • accept() используется на стороне сервера. Он принимает полученную входящую попытку создания нового TCP-соединения от удаленного клиента и создает новый сокет, связанный с парой адресов сокетов этого соединения.
  • send() , recv() , sendto() и recvfrom() используются для отправки и получения данных. Стандартные функции write() и read() также могут быть использованы.
  • close() заставляет систему освободить ресурсы, выделенные сокету. В случае TCP соединение разрывается.
  • gethostbyname() и gethostbyaddr() используются для разрешения имен хостов и адресов. Только IPv4.
  • getaddrinfo() и freeaddrinfo() используются для разрешения имен и адресов хостов. IPv4, IPv6.
  • select() используется для приостановки, ожидания, пока один или несколько сокетов из предоставленного списка не будут готовы к чтению, готовы к записи или не будут иметь ошибок.
  • poll() используется для проверки состояния сокета в наборе сокетов. Набор можно протестировать, чтобы увидеть, можно ли записать в какой-либо сокет, прочитать из него или произошла ли ошибка.
  • getsockopt() используется для получения текущего значения конкретной опции сокета для указанного сокета.
  • setsockopt() используется для установки определенного параметра сокета для указанного сокета.

розетка

Функция socket() создает конечную точку для связи и возвращает файловый дескриптор для сокета. Она использует три аргумента:

  • domain , который определяет семейство протоколов созданного сокета. Например:
    • AF_INET для сетевого протокола IPv4 (только IPv4)
    • AF_INET6 для IPv6 (и в некоторых случаях обратно совместим с IPv4)
    • AF_UNIX для локального сокета (использует специальный узел файловой системы)
  • тип , один из:
    • SOCK_STREAM (надежный потоково-ориентированный сервис или потоковые сокеты )
    • SOCK_DGRAM (служба датаграмм или сокеты датаграмм )
    • SOCK_SEQPACKET (надежная служба последовательной передачи пакетов)
    • SOCK_RAW (сырые протоколы поверх сетевого уровня)
  • protocol, указывающий фактический транспортный протокол для использования. Наиболее распространенными являются IPPROTO_TCP , IPPROTO_SCTP , IPPROTO_UDP , IPPROTO_DCCP . Эти протоколы указаны в файле netinet/in.h . Значение 0 может использоваться для выбора протокола по умолчанию из выбранного домена и типа.

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

связывать

bind() связывает сокет с адресом. Когда сокет создается с помощью socket() , ему присваивается только семейство протоколов, но не назначается адрес. Эта ассоциация должна быть выполнена до того, как сокет сможет принимать соединения с других хостов. Функция имеет три аргумента:

  • sockfd , дескриптор, представляющий сокет
  • my_addr — указатель на структуру sockaddr, представляющую адрес для привязки.
  • addrlen — поле типа socklen_t, определяющее размер структуры sockaddr .

bind() возвращает 0 в случае успеха и -1 в случае ошибки.

слушать

После того, как сокет был связан с адресом, listen() подготавливает его для входящих подключений. Однако это необходимо только для потокоориентированных (ориентированных на соединение) режимов данных, т. е. для типов сокетов ( SOCK_STREAM , SOCK_SEQPACKET ). listen() требует два аргумента:

  • sockfd , действительный дескриптор сокета.
  • backlog , целое число, представляющее количество ожидающих соединений, которые могут быть поставлены в очередь в любой момент времени. Операционная система обычно устанавливает ограничение на это значение.

После принятия соединения оно удаляется из очереди. В случае успеха возвращается 0. В случае ошибки возвращается -1.

принимать

Когда приложение прослушивает потоковые соединения от других хостов, оно уведомляется о таких событиях (ср. функцию select() ) и должно инициализировать соединение с помощью функции accept() . Она создает новый сокет для каждого соединения и удаляет соединение из очереди прослушивания. Функция имеет следующие аргументы:

  • sockfd — дескриптор прослушивающего сокета, соединение которого поставлено в очередь.
  • cliaddr , указатель на структуру sockaddr для получения информации об адресе клиента.
  • addrlen , указатель на местоположение socklen_t , которое определяет размер структуры адреса клиента, переданной в accept(). Когда accept() возвращается, это местоположение содержит размер (в байтах) структуры.

accept() возвращает новый дескриптор сокета для принятого соединения или значение -1 , если произошла ошибка. Вся дальнейшая коммуникация с удаленным хостом теперь происходит через этот новый сокет.

Сокеты датаграмм не требуют обработки с помощью accept(), поскольку получатель может немедленно ответить на запрос, используя прослушивающий сокет.

соединять

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

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

connect() возвращает целое число, представляющее код ошибки: 0 представляет успех, а –1 представляет ошибку. Исторически сложилось так, что в системах, производных от BSD, состояние дескриптора сокета не определено, если вызов connect не удается (как указано в спецификации Single Unix), поэтому переносимые приложения должны немедленно закрыть дескриптор сокета и получить новый дескриптор с помощью socket(), в случае, если вызов connect() не удается. [5]

gethostbyname и gethostbyaddr

Функции gethostbyname() и gethostbyaddr() используются для разрешения имен и адресов хостов в системе доменных имен или других механизмах разрешения локального хоста (например, поиск /etc/hosts). Они возвращают указатель на объект типа struct hostent , который описывает хост протокола Интернета . Функции используют следующие аргументы:

  • name указывает имя хоста.
  • addr указывает указатель на структуру in_addr, содержащую адрес хоста.
  • len указывает длину addr в байтах .
  • type указывает тип семейства адресов (например, AF_INET) адреса хоста.

Функции возвращают указатель NULL в случае ошибки, в этом случае можно проверить внешнее целое число h_errno , чтобы узнать, является ли это временным сбоем или недействительным или неизвестным хостом. В противном случае возвращается допустимая структура hostent * .

Эти функции не являются строго компонентом API сокета BSD, но часто используются в сочетании с функциями API для поиска хоста. Эти функции теперь считаются устаревшими интерфейсами для запросов к системе доменных имен. Были определены новые функции, которые полностью не зависят от протокола (поддерживая IPv6). Эти новые функции — getaddrinfo() и getnameinfo() , и они основаны на новой структуре данных addrinfo . [6]

Эта пара функций появилась в то же время, что и API сокетов BSD в 4.2BSD (1983), [7] в том же году, когда впервые была создана DNS. Ранние версии не запрашивали DNS и выполняли только поиск /etc/hosts. Версия 4.3BSD (1984) добавила DNS грубым способом. Текущая реализация с использованием Name Service Switch происходит от Solaris и более поздней NetBSD 1.4 (1999). [8] Первоначально определенная для NIS+ , NSS делает DNS лишь одним из многих вариантов поиска этими функциями, и его использование может быть отключено даже сегодня. [9]

Протокол и адрес семьи

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

Ниже приведен список выборки семейств протоколов (со стандартным символьным идентификатором), определенных в современной реализации Linux или BSD :

ИдентификаторФункция или использование
PF_APPLETALKAppleTalk
PF_ATMPVCАсинхронный режим передачи данных Постоянные виртуальные цепи
PF_ATMSVCАсинхронный режим передачи коммутируемых виртуальных цепей
ПФ_AX25Любительское радио AX.25
ПФ_КАНКонтроллерная локальная сеть
PF_BLUETOOTHBluetooth- розетки
PF_BRIDGEМногопротокольный мост
PF_DECnetЗарезервировано для проекта DECnet
ПФ_ЭКОНЕТЭкоСеть Желудь
ПФ_ИНЕТИнтернет-протокол версии 4
PF_INET6Интернет-протокол версии 6
PF_IPXМежсетевой пакетный обмен Novell
PF_IRDAИК- разъемы
PF_KEYAPI управления ключами PF_KEY
PF_LOCAL, PF_UNIX, PF_FILEЛокально для хоста (каналы и файловый домен)
PF_NETROMЛюбительское радио NET/ROM (относится к AX.25) [10]
PF_NETBEUIЗарезервировано для проекта 802.2LLC
БЕЗОПАСНОСТЬ_PFПсевдо AF обратного вызова безопасности
PF_NETLINK, PF_ROUTEAPI маршрутизации
ПФ_ПАКЕТСокеты захвата пакетов
PF_PPPOXPPP через X -сокеты
ПФ_СНАПроект сетевой архитектуры Linux Systems (SNA)
PF_WANPIPEAPI-сокеты Sangoma Wanpipe

Сокет для связи создается с помощью socket()функции, путем указания желаемого семейства протоколов ( PF_ -идентификатор) в качестве аргумента.

Первоначальная концепция дизайна интерфейса сокета различала типы протоколов (семейства) и конкретные типы адресов, которые каждый из них может использовать. Предполагалось, что семейство протоколов может иметь несколько типов адресов. Типы адресов определялись дополнительными символическими константами с использованием префикса AF вместо PF . Идентификаторы AF предназначены для всех структур данных, которые имеют дело с типом адреса, а не с семейством протоколов. Однако эта концепция разделения протокола и типа адреса не нашла поддержки реализации, и константы AF определялись соответствующим идентификатором протокола, оставляя различие между константами AF и PF как технический аргумент без практических последствий. Действительно, существует много путаницы в правильном использовании обеих форм. [11]

Спецификация POSIX.1—2008 не определяет никаких PF -констант, а только AF -константы [12]

Необработанные розетки

Необработанные сокеты предоставляют простой интерфейс, который обходит обработку стеком TCP/IP хоста. Они позволяют реализовать сетевые протоколы в пространстве пользователя и помогают в отладке стека протоколов. [13] Необработанные сокеты используются некоторыми службами, такими как ICMP , которые работают на уровне Интернета модели TCP/IP.

Блокирующий и неблокирующий режим

Розетки Berkeley могут работать в одном из двух режимов: блокирующем и неблокирующем.

Блокирующий сокет не возвращает управление, пока не отправит (или не получит) некоторые или все данные, указанные для операции. Для блокирующего сокета нормально не отправлять все данные. Приложение должно проверить возвращаемое значение, чтобы определить, сколько байт было отправлено или получено, и оно должно повторно отправить любые данные, которые еще не обработаны. [14] При использовании блокирующих сокетов следует уделить особое внимание accept(), поскольку он может все еще блокироваться после указания читаемости, если клиент отключается во время фазы подключения.

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

Сокет обычно устанавливается в блокирующий или неблокирующий режим с помощью функций fcntl и ioctl .

Оконечные розетки

Операционная система не освобождает ресурсы, выделенные сокету, пока сокет не будет закрыт. Это особенно важно, если вызов connect не удается и будет повторен.

Когда приложение закрывает сокет, уничтожается только интерфейс сокета. Ядро отвечает за внутреннее уничтожение сокета. Иногда сокет может войти в состояние TIME_WAIT на стороне сервера на срок до 4 минут. [15]

В системах SVR4 использование close()может привести к отбрасыванию данных. Использование shutdown()или SO_LINGER может потребоваться в этих системах для гарантии доставки всех данных. [16]

Пример клиент-сервер с использованием TCP

Transmission Control Protocol (TCP) — это протокол , ориентированный на соединение , который предоставляет множество функций исправления ошибок и производительности для передачи потоков байтов. Процесс создает сокет TCP, вызывая функцию socket()с параметрами для семейства протоколов ( PF INET , PF_INET6 ), режима сокета для потоковых сокетов ( SOCK_STREAM ) и идентификатора протокола IP для TCP ( IPPROTO_TCP ).

Сервер

Создание TCP-сервера включает в себя следующие основные шаги:

  • Создание TCP-сокета с помощью вызова socket().
  • Привязка сокета к прослушиваемому порту ( bind() ) после установки номера порта.
  • Подготовка сокета к прослушиванию соединений (превращение его в прослушивающий сокет) с помощью вызова listen() .
  • Принятие входящих соединений ( accept() ). Это блокирует процесс до тех пор, пока не будет получено входящее соединение, и возвращает дескриптор сокета для принятого соединения. Начальный дескриптор остается прослушивающим дескриптором, и accept() может быть вызван снова в любое время с этим сокетом, пока он не будет закрыт.
  • Взаимодействие с удаленным хостом с помощью функций API send() и recv() , а также с помощью функций общего назначения write() и read() .
  • Закрытие каждого сокета, который был открыт после использования с функцией close()

Следующая программа создает TCP-сервер, прослушивающий порт номер 1100:

 #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include < stdlib.h> #include <string.h> #include <unistd.h> int main ( void ) { struct sockaddr_in sa ; int SocketFD = socket ( PF_INET , SOCK_STREAM , IPPROTO_TCP ); if ( SocketFD == -1 ) { perror ( " невозможно создать сокет " ) ; exit ( EXIT_FAILURE ) ; } memset ( & sa , 0 , sizeof sa ) ; sa.sin_family = AF_INET ; sa.sin_port = htons ( 1100 ) ; sa.sin_addr . s_addr = htonl ( INADDR_ANY ); if ( bind ( SocketFD ,( struct sockaddr * ) & sa , sizeof sa ) == -1 ) { perror ( "связывание не удалось" ); close ( SocketFD ); exit ( EXIT_FAILURE ); } if ( listen ( SocketFD , 10 ) == -1 ) { perror ( "прослушивание не удалось" ); close ( SocketFD ); exit ( EXIT_FAILURE ); } for (;;) { int ConnectFD = accept ( SocketFD , NULL , NULL ); if ( ConnectFD == -1 ) { perror ( "принять не удалось" ); close ( SocketFD );                                                                                               exit ( EXIT_FAILURE ); } /* выполнение операций чтения и записи ...  read(ConnectFD, buff, size)  */ if ( shutdown ( ConnectFD , SHUT_RDWR ) == -1 ) { perror ( "выключение не удалось" ); close ( ConnectFD ); close ( SocketFD ); exit ( EXIT_FAILURE ); } close ( ConnectFD ); }                  закрыть ( SocketFD ); вернуть EXIT_SUCCESS ; }   

Клиент

Программирование клиентского приложения TCP включает следующие этапы:

  • Создание TCP-сокета.
  • Подключение к серверу ( connect() ) осуществляется путем передачи sockaddr_inструктуры с sin_familyустановленным значением AF_INET , установленным на порт, который прослушивает конечная точка (в сетевом порядке байтов), и установленным на IP-адрес прослушивающего сервера (также в сетевом порядке байтов).sin_portsin_addr
  • Взаимодействие с удаленным хостом с помощью функций API send() и recv() , а также с помощью функций общего назначения write() и read() .
  • Закрытие каждого сокета, открытого после использования функции close().
 #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include < stdlib.h> #include <string.h> #include <unistd.h> int main ( void ) { struct sockaddr_in sa ; int res ; int SocketFD ;                           SocketFD = socket ( PF_INET , SOCK_STREAM , IPPROTO_TCP ); if ( SocketFD == -1 ) { perror ( "невозможно создать сокет" ) ; exit ( EXIT_FAILURE ) ; } memset ( & sa , 0 , sizeof sa ); sa.sin_family = AF_INET ; sa.sin_port = htons ( 1100 ) ; res = inet_pton ( AF_INET , " 192.168.1.3 " , & sa.sin_addr ) ;                              если ( connect ( SocketFD , ( struct sockaddr * ) & sa , sizeof sa ) ​​== -1 ) { perror ( "connect failed" ); close ( SocketFD ); exit ( EXIT_FAILURE ); } /* выполнение операций чтения и записи ... */ close ( SocketFD ); return EXIT_SUCCESS ; }                    

Пример клиент-сервер с использованием UDP

Протокол пользовательских дейтаграмм (UDP) — это протокол без установления соединения без гарантии доставки. Пакеты UDP могут приходить не по порядку, несколько раз или вообще не приходить. Благодаря этой минимальной конструкции, UDP имеет значительно меньше накладных расходов, чем TCP. Отсутствие соединения означает, что нет понятия потока или постоянного соединения между двумя хостами. Такие данные называются дейтаграммами ( сокетами дейтаграмм ).

Адресное пространство UDP, пространство номеров портов UDP (в терминологии ISO — TSAP ), полностью отделено от пространства портов TCP.

Сервер

Приложение может настроить UDP-сервер на порту 7654 следующим образом. Программа содержит бесконечный цикл, который получает UDP-датаграммы с помощью функции recvfrom() .

#include <stdio.h> #include <errno.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <unistd.h> /* для close() для сокета */ #include <stdlib.h>        int main ( void ) { int sock ; struct sockaddr_in sa ; char buffer [ 1024 ]; ssize_t recsize ; socklen_t fromlen ;              memset ( & sa , 0 , sizeof sa ); са . sin_family = AF_INET ; са . грех_адрес . s_addr = htonl ( INADDR_ANY ); са . sin_port = htons ( 7654 ); fromlen = sizeof sa ;                 sock = socket ( PF_INET , SOCK_DGRAM , IPPROTO_UDP );     если ( bind ( sock , ( struct sockaddr * ) & sa , sizeof sa ) ​​== -1 ) { perror ( "ошибка привязки не удалась" ); закрыть ( sock ); выйти ( EXIT_FAILURE ); }               for (;;) { recsize = recvfrom ( sock , ( void * ) buffer , sizeof buffer , 0 , ( struct sockaddr * ) & sa , & fromlen ); if ( recsize < 0 ) { fprintf ( stderr , "%s \n " , strerror ( errno )); exit ( EXIT_FAILURE ); } printf ( "recsize: %d \n " , ( int ) recsize ); sleep ( 1 ); printf ( "датаграмма: %.*s \n " , ( int ) recsize , buffer ); } }                             

Клиент

Ниже представлена ​​клиентская программа для отправки UDP-пакета, содержащего строку «Hello World!», на адрес 127.0.0.1 через порт 7654.

#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h>         int main ( void ) { int sock ; struct sockaddr_in sa ; int bytes_sent ; char buffer [ 200 ]; strcpy ( buffer , "hello world!" ); /* создаем Интернет, датаграмму, сокет с использованием UDP */ sock = socket ( PF_INET , SOCK_DGRAM , IPPROTO_UDP ); if ( sock == -1 ) { /* если сокет не удалось инициализировать, выходим */ printf ( "Error Creating Socket" ); exit ( EXIT_FAILURE ); } /* Обнуляем адрес сокета */ memset ( & sa , 0 , sizeof sa ); /* Адрес - IPv4 */ sa . sin_family = AF_INET ; /* Адрес IPv4 - это uint32_t, преобразуем строковое представление октетов в соответствующее значение */ sa . sin_addr . s_addr = inet_addr ( "127.0.0.1" ); /* сокеты — это беззнаковые короткие порты, htons(x) гарантирует, что x находится в сетевом порядке байтов, установить порт на 7654 */ sa . sin_port = htons ( 7654 ); bytes_sent = sendto ( sock , buffer , strlen ( buffer ), 0 ,( struct sockaddr * ) & sa , sizeof sa ); if ( bytes_sent < 0 ) { printf ( "Ошибка отправки пакета: %s \n " , strerror ( errno )); exit ( EXIT_FAILURE ); } close ( sock ); /* закрыть сокет */ return 0 ; }                                                                          

В этом коде buffer — это указатель на отправляемые данные, а buffer_length указывает размер данных.

Ссылки

  1. ^ Например, в языке программирования Ruby ruby-doc::Socket
  2. ^ "— Спецификация POSIX.1-2008". Opengroup.org . Получено 2012-07-26 .
  3. ^ «Организация сетей в Плане 9».
  4. ^ «Стек TCP/IP Linux как плагин VFS».
  5. ^ Стивенс и Раго 2013, стр. 607.
  6. ^ POSIX.1-2004
  7. ^ gethostbyname(3)  –  Руководство по функциям библиотеки FreeBSD
  8. Конилл, Ариадна (27 марта 2022 г.). «трагедия gethostbyname». ariadne.space .
  9. ^ nsswitch.conf(5)  –  Руководство по форматам файлов FreeBSD
  10. ^ https://manpages.debian.org/experimental/ax25-tools/netrom.4.en.html. {{cite web}}: Отсутствует или пусто |title=( помощь )
  11. ^ Сетевое программирование UNIX , том 1, третье издание: API сетевых сокетов, У. Ричард Стивенс, Билл Феннер, Эндрю М. Рудофф, Эддисон Уэсли, 2003.
  12. ^ "The Open Group Base Specifications Issue 7". Pubs.opengroup.org . Получено 2012-07-26 .
  13. ^ "TCP/IP raw sockets - Win32 apps". 19 января 2022 г.
  14. ^ "Руководство Beej по сетевому программированию". Beej.us. 2007-05-05 . Получено 2012-07-26 .
  15. ^ "терминирующие сокеты". Softlab.ntua.gr . Получено 2012-07-26 .
  16. ^ "ntua.gr - Программирование сокетов UNIX на языке C - Часто задаваемые вопросы: вопросы, касающиеся как клиентов, так и серверов (TCP/SOCK_STREAM)". Softlab.ntua.gr . Получено 26.07.2012 .

Юридически стандартное определение интерфейса Sockets содержится в стандарте POSIX, известном как:

  • IEEE Std. 1003.1-2001 Стандарт информационных технологий — Интерфейс переносимых операционных систем (POSIX).
  • Технический стандарт Open Group: Базовые спецификации, выпуск 6, декабрь 2001 г.
  • ИСО/МЭК 9945:2002

Информация об этом стандарте и текущей работе над ним доступна на веб-сайте Остина.

Расширения IPv6 для API базовых сокетов задокументированы в RFC 3493 и RFC 3542.

  • Стивенс, В. Ричард; Раго, Стивен А. (24 мая 2013 г.). Advanced Programming in the UNIX Environment (Третье изд.). Addison-Wesley Professional . ISBN 978-0321637734. Получено 27 февраля 2015 г.
  • Дополнительные документы для программистов UNIX (PSD: 20-1)
  • Руководство Биджа по сетевому программированию - 2007
  • Перенос программ Berkeley Socket на Winsock — документация Microsoft.
  • Программирование сокетов UNIX на языке C — часто задаваемые вопросы — 1996
  • Сетевое программирование Linux - Linux Journal , 1998
Взято с "https://en.wikipedia.org/w/index.php?title=Berkeley_sockets&oldid=1260804502"