Документация Python неофициальный перевод
Содержание страницы

18.1. socket – Низкоуровневый сетевой интерфейсsocket – Low-level networking interface

Исходный код: Lib/socket.py


Этот модуль предоставляет доступ к интерфейсу сокетов BSD. Он доступен во всех современных системах Unix, Windows, MacOS и, возможно, на других платформах.

Примечание

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

Интерфейс Python представляет собой прямую трансляцию системных вызовов Unix и библиотечного интерфейса сокетов в объектно-ориентированный стиль Python: функция socket() возвращает объект сокета, методы которого реализуют различные системные вызовы сокетов. Типы параметров несколько более высокоуровневые, чем в интерфейсе C: как и при операциях read() и write() с файлами Python, выделение буфера при операциях приёма происходит автоматически, а длина буфера неявно задаётся при отправке.

См. также

Модуль socketserver
Классы, упрощающие написание сетевых серверов.
Модуль ssl
Обёртка TLS/SSL для объектов сокетов.

18.1.1. Семейства сокетовSocket families

В зависимости от системы и параметров сборки этим модулем поддерживаются различные семейства сокетов.

Формат адреса, требуемый для конкретного объекта сокета, автоматически выбирается на основе семейства адресов, указанного при создании объекта сокета. Адреса сокетов представляются следующим образом:

  • Адрес сокета AF_UNIX, привязанного к узлу файловой системы, представляется в виде строки с использованием кодировки файловой системы и обработчика ошибок 'surrogateescape' (см. PEP 383). Адрес в абстрактном пространстве имён Linux возвращается как байтоподобный объект с начальным нулевым байтом; обратите внимание, что сокеты в этом пространстве имён могут взаимодействовать с обычными файловыми сокетами, поэтому программы, предназначенные для работы в Linux, возможно, должны работать с обоими типами адресов. Строка или байтоподобный объект могут использоваться для любого из этих типов адресов при передаче в качестве аргумента.

    Изменено в версии 3.3: Ранее предполагалось, что пути сокетов AF_UNIX используют кодировку UTF-8.

    Изменено в версии 3.5: Теперь принимается записываемый байтоподобный объект.

  • Пара (host, port) используется для семейства адресов AF_INET, где host – строка, представляющая либо имя узла в нотации интернет-домена например 'daring.cwi.nl', либо IPv4-адрес, например '100.50.200.5', а port – целое число.

  • Для семейства адресов AF_INET6 используется четырёхэлементный кортеж (host, port, flowinfo, scopeid), где flowinfo и scopeid представляют члены sin6_flowinfo и sin6_scope_id в struct sockaddr_in6 в C. Для методов модуля socket flowinfo и scopeid можно опускать только для обратной совместимости. Однако учтите, что опускание scopeid может вызвать проблемы при работе с scoped IPv6-адресами.

  • Сокеты AF_NETLINK представляются в виде пар (pid, groups).

  • Поддержка TIPC только в Linux доступна через семейство адресов AF_TIPC. TIPC – это открытый сетевой протокол, не основанный на IP, предназначенный для использования в кластерных средах. Адреса представляются кортежем, и поля зависят от типа адреса. Общий вид кортежа: (addr_type, v1, v2, v3 [, scope]), где:

    • addr_type – одно из значений TIPC_ADDR_NAMESEQ, TIPC_ADDR_NAME или TIPC_ADDR_ID.

    • scope – одно из значений TIPC_ZONE_SCOPE, TIPC_CLUSTER_SCOPE и TIPC_NODE_SCOPE.

    • Если addr_type равно TIPC_ADDR_NAME, то v1 – тип сервера, v2 – идентификатор порта, а v3 должно быть 0.

      Если addr_type равно TIPC_ADDR_NAMESEQ, то v1 – тип сервера, v2 – нижний номер порта, а v3 – верхний номер порта.

      Если addr_type равно TIPC_ADDR_ID, то v1 – узел, v2 – ссылка, а v3 должно быть установлено в 0.

  • Кортеж (interface, ) используется для семейства адресов AF_CAN, где interface – строка, представляющая имя сетевого интерфейса, например 'can0'. Имя сетевого интерфейса '' может использоваться для приёма пакетов от всех сетевых интерфейсов данного семейства.

  • Строка или кортеж (id, unit) используется для протокола SYSPROTO_CONTROL семейства PF_SYSTEM. Строка – это имя управления ядра с динамически назначаемым ID. Кортеж можно использовать, если ID и номер модуля управления ядра известны или используется зарегистрированный ID.

    Новое в версии 3.3.

  • AF_BLUETOOTH поддерживает следующие протоколы и форматы адресов:

    • BTPROTO_L2CAP принимает (bdaddr, psm), где bdaddr – адрес Bluetooth в виде строки, а psm – целое число.

    • BTPROTO_RFCOMM принимает (bdaddr, channel), где bdaddr – это Bluetooth-адрес в виде строки, а channel – целое число.

    • BTPROTO_HCI принимает (device_id,), где device_id – это либо целое число, либо строка с Bluetooth-адресом интерфейса. (Зависит от ОС: NetBSD и DragonFlyBSD ожидают Bluetooth-адрес, все остальные – целое число.)

      Изменено в версии 3.2: Добавлена поддержка NetBSD и DragonFlyBSD.

    • BTPROTO_SCO принимает bdaddr, где bdaddr – это объект bytes, содержащий Bluetooth-адрес в строковом формате (например, b'12:23:34:45:56:67'). Этот протокол не поддерживается в FreeBSD.

  • Некоторые другие семейства адресов (AF_PACKET, AF_CAN) поддерживают определённые представления.

Для IPv4-адресов вместо адреса хоста принимаются две особые формы: пустая строка обозначает INADDR_ANY, а строка '<broadcast>' обозначает INADDR_BROADCAST. Это поведение несовместимо с IPv6, поэтому, если предполагается поддержка IPv6 в программах на Python, от их использования лучше отказаться.

Если в части узел адреса сокета IPv4/v6 указано имя узла, программа может демонстрировать недетерминированное поведение, так как Python использует первый адрес, возвращённый при разрешении DNS. Адрес сокета будет разрешаться по-разному в фактический IPv4/v6-адрес в зависимости от результатов разрешения DNS и/или конфигурации узла. Для детерминированного поведения используйте числовой адрес в части узел.

Все ошибки порождают исключения. Могут возникать обычные исключения для неверных типов аргументов и нехватки памяти; начиная с Python 3.3, ошибки, связанные с семантикой сокетов или адресов, порождают OSError или один из его подклассов (раньше они порождали socket.error).

Неблокирующий режим поддерживается через setblocking(). Его обобщение на основе тайм-аутов поддерживается через settimeout().

18.1.2. Содержание модуляModule contents

Модуль socket экспортирует следующие элементы.

18.1.2.1. ИсключенияExceptions

exception socket.error

Устаревший псевдоним OSError.

Изменено в версии 3.3: В соответствии с PEP 3151 этот класс стал псевдонимом OSError.

exception socket.herror

Подкласс OSError, это исключение возникает при ошибках, связанных с адресами, т.е. для функций, использующих h_errno в POSIX C API, включая gethostbyname_ex() и gethostbyaddr(). Сопутствующее значение – пара (h_errno, string), представляющая ошибку, возвращённую библиотечным вызовом. h_errno – числовое значение, а строка представляет описание h_errno, возвращаемое функцией языка C hstrerror().

Изменено в версии 3.3: Этот класс стал подклассом OSError.

exception socket.gaierror

Подкласс OSError, это исключение возникает при ошибках, связанных с адресами, функциями getaddrinfo() и getnameinfo(). Сопутствующее значение – пара (error, string), представляющая ошибку, возвращённую библиотечным вызовом. строка представляет описание error, возвращаемое функцией языка C gai_strerror(). Числовое значение error будет соответствовать одной из констант EAI_*, определённых в этом модуле.

Изменено в версии 3.3: Этот класс стал подклассом OSError.

exception socket.timeout

Подкласс OSError, это исключение возникает при возникновении тайм-аута на сокете, для которого тайм-ауты были включены с помощью предыдущего вызова settimeout() (или неявно через setdefaulttimeout()). Сопутствующее значение – строка, которая в настоящее время всегда равна «timed out».

Изменено в версии 3.3: Этот класс стал подклассом OSError.

18.1.2.2. КонстантыConstants

Константы AF_* и SOCK_* теперь являются AddressFamily и SocketKind IntEnum коллекциями.

Новое в версии 3.4.

socket.AF_UNIX
socket.AF_INET
socket.AF_INET6

Эти константы представляют семейства адресов (и протоколов), используемые для первого аргумента socket(). Если константа AF_UNIX не определена, то данный протокол не поддерживается. В зависимости от системы могут быть доступны дополнительные константы.

socket.SOCK_STREAM
socket.SOCK_DGRAM
socket.SOCK_RAW
socket.SOCK_RDM
socket.SOCK_SEQPACKET

Эти константы представляют типы сокетов, которые используются для второго аргумента socket(). В зависимости от системы могут быть доступны и другие константы. (Обычно полезны только SOCK_STREAM и SOCK_DGRAM.)

socket.SOCK_CLOEXEC
socket.SOCK_NONBLOCK

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

См. также

Безопасная обработка файловых дескрипторов для более подробного объяснения.

Доступность: Linux >= 2.6.27.

Новое в версии 3.2.

SO_*
socket.SOMAXCONN
MSG_*
SOL_*
SCM_*
IPPROTO_*
IPPORT_*
INADDR_*
IP_*
IPV6_*
EAI_*
AI_*
NI_*
TCP_*

Многие константы этих форм, описанные в документации Unix по сокетам и/или протоколу IP, также определены в модуле socket. Они обычно используются в аргументах методов setsockopt() и getsockopt() объектов сокетов. В большинстве случаев определены только те символы, которые есть в заголовочных файлах Unix; для некоторых символов предоставлены значения по умолчанию.

socket.AF_CAN
socket.PF_CAN
SOL_CAN_*
CAN_*

Множество констант такого вида, описанных в документации Linux, также определены в модуле socket.

Доступность: Linux >= 2.6.25.

Новое в версии 3.3.

socket.CAN_BCM
CAN_BCM_*

CAN_BCM в семействе протоколов CAN – это протокол broadcast manager (BCM). Константы broadcast manager, описанные в документации Linux, также определены в модуле socket.

Доступность: Linux >= 2.6.25.

Новое в версии 3.4.

socket.CAN_RAW_FD_FRAMES

Включает поддержку CAN FD в сокете CAN_RAW. По умолчанию отключено. Это позволяет вашему приложению отправлять как CAN, так и CAN FD кадры; однако, при чтении из сокета необходимо принимать как CAN, так и CAN FD кадры.

Эта константа описана в документации Linux.

Доступность: Linux >= 3.6.

Новое в версии 3.5.

socket.AF_RDS
socket.PF_RDS
socket.SOL_RDS
RDS_*

Множество констант такого вида, описанных в документации Linux, также определены в модуле socket.

Доступность: Linux >= 2.6.30.

Новое в версии 3.3.

SIO_*
RCVALL_*

Константы для Windows’ WSAIoctl(). Эти константы используются в качестве аргументов метода ioctl() объектов сокетов.

TIPC_*

Константы, связанные с TIPC, соответствующие тем, что экспортируются C API сокетов. Дополнительную информацию см. в документации TIPC.

Доступность: BSD, OSX.

Новое в версии 3.4.

socket.has_ipv6

Эта константа содержит логическое значение, указывающее, поддерживается ли IPv6 на данной платформе.

socket.BDADDR_ANY
socket.BDADDR_LOCAL

Это строковые константы, содержащие Bluetooth-адреса со специальным значением. Например, BDADDR_ANY можно использовать для указания любого адреса при задании сокета привязки с помощью BTPROTO_RFCOMM.

socket.HCI_FILTER
socket.HCI_TIME_STAMP
socket.HCI_DATA_DIR

Для использования с BTPROTO_HCI. HCI_FILTER недоступен в NetBSD или DragonFlyBSD. HCI_TIME_STAMP и HCI_DATA_DIR недоступны в FreeBSD, NetBSD или DragonFlyBSD.

18.1.2.3. ФункцииFunctions

18.1.2.3.1. Создание сокетовCreating sockets

Все следующие функции создают объекты сокетов.

socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)

Создаёт новый сокет с заданным семейством адресов, типом сокета и номером протокола. Семейство адресов должно быть AF_INET (по умолчанию), AF_INET6, AF_UNIX, AF_CAN или AF_RDS. Тип сокета должен быть SOCK_STREAM (по умолчанию), SOCK_DGRAM, SOCK_RAW или, возможно, одной из других констант SOCK_. Номер протокола обычно равен нулю и может быть опущен; в случае, если семейство адресов – AF_CAN, протокол должен быть одним из CAN_RAW или CAN_BCM. Если указан параметр fileno, остальные аргументы игнорируются, и возвращается сокет с указанным файловым дескриптором. В отличие от socket.fromfd(), fileno вернёт тот же сокет, а не его копию. Это может помочь закрыть отсоединённый сокет с помощью socket.close().

Новый созданный сокет ненаследуемый.

Изменено в версии 3.3: Добавлено семейство AF_CAN. Добавлено семейство AF_RDS.

Изменено в версии 3.4: Добавлен протокол CAN_BCM.

Изменено в версии 3.4: Возвращаемый сокет теперь ненаследуемый.

socket.socketpair([family[, type[, proto]]])

Создаёт пару связанных объектов сокетов, используя заданное семейство адресов, тип сокета и номер протокола. Семейство адресов, тип сокета и номер протокола те же, что и для функции socket() выше. Семейство по умолчанию – AF_UNIX, если оно определено на платформе; в противном случае по умолчанию используется AF_INET.

Новые созданные сокеты ненаследуемые.

Изменено в версии 3.2: Возвращаемые объекты сокетов теперь поддерживают полный API сокетов, а не подмножество.

Изменено в версии 3.4: Возвращаемые сокеты теперь являются ненаследуемыми.

Изменено в версии 3.5: Добавлена поддержка Windows.

socket.create_connection(address[, timeout[, source_address]])

Подключается к TCP-службе, прослушивающей адрес в интернете (кортеж из двух элементов (host, port)), и возвращает объект сокета. Это функция более высокого уровня, чем socket.connect(): если host – нечисловое имя узла, он будет пытаться разрешить его как для AF_INET, так и для AF_INET6, а затем пытаться подключаться ко всем возможным адресам по очереди, пока подключение не установится. Это упрощает написание клиентов, совместимых как с IPv4, так и с IPv6.

Передача необязательного параметра timeout установит тайм-аут для экземпляра сокета перед попыткой подключения. Если timeout не указан, используется глобальная настройка тайм-аута по умолчанию, возвращаемая getdefaulttimeout().

Если указан, source_address должен быть кортежем из двух элементов (host, port), к которому сокет должен привязаться как к своему исходному адресу перед подключением. Если хост или порт равны '' или 0 соответственно, будет использовано поведение ОС по умолчанию.

Изменено в версии 3.2: Добавлен параметр source_address.

socket.fromfd(fd, family, type, proto=0)

Дублирует файловый дескриптор fd (целое число, возвращаемое методом fileno() объекта файла) и создаёт объект сокета из результата. Семейство адресов, тип сокета и номер протокола такие же, как для функции socket() выше. Файловый дескриптор должен указывать на сокет, но это не проверяется – последующие операции с объектом могут завершиться ошибкой, если файловый дескриптор некорректен. Эта функция требуется редко, но может использоваться для получения или установки параметров сокета, переданного программе как стандартный ввод или вывод (например, сервер, запущенный демоном inet в Unix). Предполагается, что сокет находится в блокирующем режиме.

Новый созданный сокет ненаследуемый.

Изменено в версии 3.4: Возвращаемый сокет теперь ненаследуемый.

socket.fromshare(data)

Создаёт экземпляр сокета из данных, полученных из метода socket.share(). Предполагается, что сокет находится в блокирующем режиме.

Доступность: Windows.

Новое в версии 3.3.

socket.SocketType

Это объект типа Python, представляющий тип объекта сокета. Он аналогичен type(socket(...)).

18.1.2.3.2. Другие функцииOther functions

Модуль socket также предоставляет различные сетевые службы:

socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)

Преобразует аргументы host/port в последовательность кортежей из 5 элементов, содержащих все необходимые аргументы для создания сокета, подключенного к этому сервису. host – это доменное имя, строковое представление IPv4/v6-адреса или None. port – это строковое имя службы, такое как 'http', числовой номер порта или None. Передавая None в качестве значения host и port, можно передать NULL в базовый C API.

Аргументы family, type и proto можно указать необязательно, чтобы сузить список возвращаемых адресов. Передача нуля в качестве значения каждого из этих аргументов выбирает полный диапазон результатов. Аргумент flags может быть одной или несколькими константами из AI_* и будет влиять на то, как вычисляются и возвращаются результаты. Например, AI_NUMERICHOST отключит разрешение доменных имён и вызовет исключение, если host является доменным именем.

Функция возвращает список кортежей из 5 элементов со следующей структурой:

(family, type, proto, canonname, sockaddr)

В этих кортежах family, type, proto – целые числа, предназначенные для передачи в функцию socket(). canonname будет строкой, представляющей каноническое имя хоста, если AI_CANONNAME является частью аргумента flags; в противном случае canonname будет пустым. sockaddr – это кортеж, описывающий адрес сокета, формат которого зависит от возвращённого family ((address, port) 2-кортеж для AF_INET, (address, port, flow info, scope id) 4-кортеж для AF_INET6) и предназначен для передачи в метод socket.connect().

В следующем примере получается информация об адресе для гипотетического TCP-подключения к example.org на порту 80 (результаты могут отличаться на вашей системе, если IPv6 не включён):

>>> socket.getaddrinfo("example.org", 80, proto=socket.IPPROTO_TCP)
[(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_STREAM: 1>,
 6, '', ('2606:2800:220:1:248:1893:25c8:1946', 80, 0, 0)),
 (<AddressFamily.AF_INET: 2>, <SocketType.SOCK_STREAM: 1>,
 6, '', ('93.184.216.34', 80))]

Изменено в версии 3.2: теперь параметры можно передавать в виде именованных аргументов.

socket.getfqdn([name])

Возвращает полностью определённое доменное имя для name. Если name опущен или пуст, он интерпретируется как локальный хост. Для поиска полного имени сначала проверяется имя хоста, возвращаемое gethostbyaddr(), затем, если доступны, псевдонимы хоста. Выбирается первое имя, содержащее точку. Если полностью определённое доменное имя недоступно, возвращается имя хоста, полученное от gethostname().

socket.gethostbyname(hostname)

Преобразует имя хоста в формат IPv4-адреса. IPv4-адрес возвращается в виде строки, например '100.50.200.5'. Если имя хоста само является IPv4-адресом, оно возвращается без изменений. См. gethostbyname_ex() для более полного интерфейса. gethostbyname() не поддерживает разрешение имён IPv6, вместо него для поддержки двойного стека IPv4/v6 следует использовать getaddrinfo().

socket.gethostbyname_ex(hostname)

Преобразует имя хоста в формат IPv4-адреса (расширенный интерфейс). Возвращает тройку (hostname, aliaslist, ipaddrlist), где hostname – основное имя хоста, отвечающее на заданный ip_address; aliaslist – (возможно пустой) список альтернативных имён хоста для того же адреса; и ipaddrlist – список IPv4-адресов для того же интерфейса на том же хосте (часто, но не всегда, один адрес). gethostbyname_ex() не поддерживает разрешение имён IPv6, а для поддержки IPv4/IPv6 двойного стека следует использовать getaddrinfo().

socket.gethostname()

Возвращает строку, содержащую имя хоста машины, на которой в данный момент выполняется интерпретатор Python.

Примечание: gethostname() не всегда возвращает полное доменное имя; для этого используйте getfqdn().

socket.gethostbyaddr(ip_address)

Возвращает кортеж (hostname, aliaslist, ipaddrlist), где hostname – это основное имя хоста, соответствующее заданному ip_address, aliaslist – (возможно пустой) список альтернативных имён хоста для того же адреса, а ipaddrlist – список IPv4/v6-адресов для того же интерфейса на том же хосте (скорее всего, содержащий только один адрес). Чтобы найти полностью определённое доменное имя, используйте функцию getfqdn(). gethostbyaddr() поддерживает как IPv4, так и IPv6.

socket.getnameinfo(sockaddr, flags)

Преобразует адрес сокета sockaddr в кортеж из двух элементов (host, port). В зависимости от настроек flags результат может содержать полное доменное имя или числовое представление адреса в host. Аналогично, port может содержать строковое имя порта или числовой номер порта.

socket.getprotobyname(protocolname)

Преобразует имя интернет-протокола (например, 'icmp') в константу, пригодную для передачи в качестве (необязательного) третьего аргумента функции socket(). Обычно это требуется только для сокетов, открытых в «сыром» режиме (SOCK_RAW); для обычных режимов сокетов правильный протокол выбирается автоматически, если протокол опущен или равен нулю.

socket.getservbyname(servicename[, protocolname])

Преобразует имя интернет-службы и имя протокола в номер порта для этой службы. Необязательное имя протокола, если указано, должно быть 'tcp' или 'udp', в противном случае подойдет любой протокол.

socket.getservbyport(port[, protocolname])

Преобразует номер порта интернет-службы и имя протокола в имя службы для этой службы. Необязательное имя протокола, если указано, должно быть 'tcp' или 'udp', в противном случае подойдет любой протокол.

socket.ntohl(x)

Преобразует 32-битные положительные целые числа из сетевого порядка байтов в порядок байтов хоста. На машинах, где порядок байтов хоста совпадает с сетевым, эта операция ничего не делает; в противном случае выполняется перестановка 4 байтов.

socket.ntohs(x)

Преобразует 16-битные положительные целые числа из сетевого порядка байтов в порядок байтов хоста. На машинах, где порядок байтов хоста совпадает с сетевым, эта функция ничего не делает; в противном случае она выполняет обмен двух байтов.

socket.htonl(x)

Преобразует 32-битные положительные целые числа из порядка байтов хоста в сетевой порядок. На машинах, где порядок байтов хоста совпадает с сетевым, эта функция ничего не делает; в противном случае она выполняет обмен четырёх байтов.

socket.htons(x)

Преобразует 16-битные положительные целые числа из порядка байтов хоста в сетевой порядок. На машинах, где порядок байтов хоста совпадает с сетевым, эта функция ничего не делает; в противном случае она выполняет обмен двух байтов.

socket.inet_aton(ip_string)

Преобразует IPv4-адрес из строкового формата с точками (например, ‘123.45.67.89’) в 32-битный упакованный двоичный формат в виде объекта bytes длиной четыре символа. Это полезно при взаимодействии с программой, использующей стандартную библиотеку C и требующей объекты типа struct in_addr, который является C-типом для 32-битного упакованного двоичного представления, возвращаемого этой функцией.

inet_aton() также принимает строки с менее чем тремя точками; подробнее см. на странице руководства Unix inet(3).

Если переданная функции строка IPv4-адреса недопустима, будет возбуждено OSError. Обратите внимание: что именно считается допустимым, зависит от нижележащей C-реализации inet_aton().

inet_aton() не поддерживает IPv6; для поддержки двойного стека IPv4/IPv6 следует использовать inet_pton().

socket.inet_ntoa(packed_ip)

Преобразует 32-битный упакованный IPv4-адрес (объект, подобный bytes длиной четыре байта) в стандартное строковое представление с точками (например, ‘123.45.67.89’). Это полезно при взаимодействии с программой, использующей стандартную библиотеку C и требующей объекты типа struct in_addr, который является C-типом для 32-битных упакованных двоичных данных, принимаемых этой функцией в качестве аргумента.

Если переданная функции последовательность байтов имеет длину не ровно 4 байта, будет возбуждено OSError. inet_ntoa() не поддерживает IPv6; для поддержки двойного стека IPv4/IPv6 следует использовать inet_ntop().

Изменено в версии 3.5: Теперь принимается записываемый байтоподобный объект.

socket.inet_pton(address_family, ip_string)

Преобразует IP-адрес из строкового формата, специфичного для семейства адресов, в упакованный двоичный формат. inet_pton() полезен, когда библиотека или сетевой протокол требует объект типа struct in_addr (аналогично inet_aton()) или struct in6_addr.

В настоящее время поддерживаемые значения для address_family: AF_INET и AF_INET6. Если строка IP-адреса ip_string недопустима, будет возбуждено OSError. Обратите внимание: что именно считается допустимым, зависит как от значения address_family, так и от нижележащей реализации inet_pton().

Доступность: Unix (возможно, не все платформы), Windows.

Изменено в версии 3.4: Добавлена поддержка Windows

socket.inet_ntop(address_family, packed_ip)

Преобразует упакованный IP-адрес (объект, подобный bytes некоторой длины) в стандартное строковое представление, специфичное для семейства адресов (например, '7.10.0.5' или '5aef:2b::8'). inet_ntop() полезен, когда библиотека или сетевой протокол возвращает объект типа struct in_addr (аналогично inet_ntoa()) или struct in6_addr.

В настоящее время поддерживаемые значения для address_family: AF_INET и AF_INET6. Если объект bytes packed_ip имеет неправильную длину для указанного семейства адресов, будет возбуждено ValueError. OSError возбуждается при ошибках вызова inet_ntop().

Доступность: Unix (возможно, не все платформы), Windows.

Изменено в версии 3.4: Добавлена поддержка Windows

Изменено в версии 3.5: Теперь принимается записываемый байтоподобный объект.

socket.CMSG_LEN(length)

Return the total length, without trailing padding, of an ancillary data item with associated data of the given length. This value can often be used as the buffer size for recvmsg() to receive a single item of ancillary data, but RFC 3542 requires portable applications to use CMSG_SPACE() and thus include space for padding, even when the item will be the last in the buffer. Raises OverflowError if length is outside the permissible range of values.

Доступность: большинство платформ Unix, возможно, и другие.

Новое в версии 3.3.

socket.CMSG_SPACE(length)

Возвращает размер буфера, необходимый для recvmsg() для приёма одного вспомогательного элемента данных с соответствующими данными заданной length, включая любое завершающее выравнивание. Пространство буфера, необходимое для приёма нескольких элементов, представляет собой сумму значений CMSG_SPACE() для длин их соответствующих данных. Возбуждает OverflowError, если length выходит за допустимый диапазон значений.

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

Доступность: большинство платформ Unix, возможно, и другие.

Новое в версии 3.3.

socket.getdefaulttimeout()

Возвращает тайм-аут по умолчанию в секундах (число с плавающей запятой) для новых объектов сокетов. Значение None означает, что новые объекты сокетов не имеют тайм-аута. При первом импорте модуля socket значение по умолчанию равно None.

socket.setdefaulttimeout(timeout)

Устанавливает тайм-аут по умолчанию в секундах (число с плавающей точкой) для новых объектов сокета. При первом импорте модуля socket значением по умолчанию является None. Возможные значения и их смысл описаны в settimeout().

socket.sethostname(name)

Устанавливает имя узла (hostname) машины равным name. Если прав недостаточно, будет возбуждено исключение OSError.

Доступность: Unix.

Новое в версии 3.3.

socket.if_nameindex()

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

Доступность: Unix.

Новое в версии 3.3.

socket.if_nametoindex(if_name)

Возвращает номер индекса сетевого интерфейса, соответствующий имени интерфейса. OSError, если интерфейс с таким именем не существует.

Доступность: Unix.

Новое в версии 3.3.

socket.if_indextoname(if_index)

Возвращает имя сетевого интерфейса, соответствующее номеру индекса интерфейса. OSError, если интерфейс с таким индексом не существует.

Доступность: Unix.

Новое в версии 3.3.

18.1.3. Объекты сокетовSocket Objects

Объекты сокетов имеют следующие методы. За исключением makefile(), они соответствуют системным вызовам Unix, применимым к сокетам.

Изменено в версии 3.2: Добавлена поддержка протокола менеджера контекста. Выход из менеджера контекста эквивалентен вызову close().

socket.accept()

Принимает соединение. Сокет должен быть привязан к адресу и находиться в режиме прослушивания. Возвращаемое значение – пара (conn, address), где conn – это новый объект сокета, пригодный для отправки и получения данных по соединению, а address – адрес, привязанный к сокету на другом конце соединения.

Новый созданный сокет ненаследуемый.

Изменено в версии 3.4: Сокет теперь ненаследуемый.

Изменено в версии 3.5: Если системный вызов прерван и обработчик сигнала не вызывает исключение, метод теперь повторяет системный вызов вместо того, чтобы вызывать исключение InterruptedError (см. PEP 475 с обоснованием).

socket.bind(address)

Привязывает сокет к address. Сокет не должен быть уже привязан. (Формат address зависит от семейства адресов – см. выше.)

socket.close()

Помечает сокет как закрытый. Базовый системный ресурс (например, файловый дескриптор) также закрывается, когда все файловые объекты из makefile() будут закрыты. Как только это происходит, все последующие операции с объектом сокета будут завершаться ошибкой. Удалённая сторона больше не получит данных (после сброса поставленных в очередь данных).

Сокеты автоматически закрываются при сборке мусора, но рекомендуется явно close() их закрывать или использовать оператор with вокруг них.

Примечание

close() освобождает ресурс, связанный с соединением, но не обязательно немедленно закрывает соединение. Если требуется своевременно закрыть соединение, вызовите shutdown() перед close().

socket.connect(address)

Подключается к удалённому сокету по адресу address. (Формат address зависит от семейства адресов – см. выше.)

Если соединение прерывается сигналом, метод ожидает его завершения или вызывает исключение socket.timeout по таймауту, если обработчик сигнала не возбуждает исключение, а сокет является блокирующим или имеет таймаут. Для неблокирующих сокетов метод вызывает исключение InterruptedError, если соединение прерывается сигналом (или исключение, возбуждённое обработчиком сигнала).

Изменено в версии 3.5: Теперь метод ждёт завершения соединения вместо возбуждения исключения InterruptedError, если соединение прервано сигналом, обработчик сигнала не вызывает исключение, а сокет является блокирующим или имеет тайм-аут (см. PEP 475 с обоснованием).

socket.connect_ex(address)

Как и connect(address), но возвращает индикатор ошибки вместо возбуждения исключения для ошибок, возвращаемых вызовом connect() на уровне C (другие проблемы, например «хост не найден», по-прежнему могут вызывать исключения). Индикатор ошибки равен 0, если операция выполнена успешно, в противном случае – значению переменной errno. Это удобно, например, для поддержки асинхронных подключений.

socket.detach()

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

Новое в версии 3.2.

socket.dup()

Дублирует сокет.

Новый созданный сокет ненаследуемый.

Изменено в версии 3.4: Сокет теперь ненаследуемый.

socket.fileno()

Возвращает файловый дескриптор сокета (небольшое целое число) или -1 в случае ошибки. Это полезно с select.select().

В Windows небольшое целое число, возвращаемое этим методом, нельзя использовать там, где может быть использован файловый дескриптор (например, os.fdopen()). В Unix такого ограничения нет.

socket.get_inheritable()

Получить наследуемый флаг файлового дескриптора сокета или handle сокета: True, если сокет может наследоваться в дочерних процессах, False, если не может.

Новое в версии 3.4.

socket.getpeername()

Возвращает удалённый адрес, к которому подключён сокет. Это полезно, например, для определения номера порта удалённого сокета IPv4/v6. (Формат возвращаемого адреса зависит от семейства адресов – см. выше.) На некоторых системах эта функция не поддерживается.

socket.getsockname()

Возвращает собственный адрес сокета. Это полезно, например, для определения номера порта сокета IPv4/v6. (Формат возвращаемого адреса зависит от семейства адресов – см. выше.)

socket.getsockopt(level, optname[, buflen])

Возвращает значение указанной опции сокета (см. страницу руководства Unix getsockopt(2)). Необходимые символьные константы (SO_* и т.д.) определены в этом модуле. Если buflen отсутствует, предполагается целочисленная опция и функция возвращает её целочисленное значение. Если buflen присутствует, он задаёт максимальную длину буфера для получения опции, и этот буфер возвращается в виде объекта bytes. Вызывающий код должен сам декодировать содержимое буфера (см. опциональный встроенный модуль struct для способа декодирования структур C, закодированных как строки байтов).

socket.gettimeout()

Возвращает тайм-аут в секундах (число с плавающей точкой), связанный с операциями сокета, или None, если тайм-аут не установлен. Это отражает последний вызов setblocking() или settimeout().

socket.ioctl(control, option)
Платформа:Windows

Метод ioctl() является ограниченным интерфейсом к системному интерфейсу WSAIoctl. За дополнительной информацией обратитесь к документации Win32.

На других платформах можно использовать общие функции fcntl.fcntl() и fcntl.ioctl(); они принимают объект сокета в качестве первого аргумента.

socket.listen([backlog])

Включает возможность сервера принимать соединения. Если указан backlog, он должен быть не менее 0 (если меньше, устанавливается в 0); он задаёт количество непринятых соединений, которые система разрешит до отказа в новых соединениях. Если не указан, выбирается разумное значение по умолчанию.

Изменено в версии 3.5: Параметр backlog теперь необязателен.

socket.makefile(mode='r', buffering=None, *, encoding=None, errors=None, newline=None)

Возвращает файловый объект, связанный с сокетом. Точный возвращаемый тип зависит от аргументов, переданных в makefile(). Эти аргументы интерпретируются так же, как и встроенной функцией open(), за исключением того, что единственные поддерживаемые значения режима'r' (по умолчанию), 'w' и 'b'.

Сокет должен быть в блокирующем режиме; можно установить тайм-аут, но при его срабатывании внутренний буфер файлового объекта может оказаться в несогласованном состоянии.

Закрытие файлового объекта, возвращённого makefile(), не закроет исходный сокет, если только все остальные файловые объекты не будут закрыты и для объекта сокета не будет вызван socket.close().

Примечание

В Windows файлоподобный объект, созданный makefile(), нельзя использовать там, где ожидается файловый объект с дескриптором файла, например, в аргументах потока subprocess.Popen().

socket.recv(bufsize[, flags])

Получает данные из сокета. Возвращает объект bytes с полученными данными. Максимальный объём данных за одно получение задаётся параметром bufsize. Значение необязательного аргумента flags описано на странице руководства Unix recv(2); по умолчанию он равен нулю.

Примечание

Для наилучшего соответствия реальным характеристикам оборудования и сети значение bufsize должно быть относительно небольшой степенью двойки, например, 4096.

Изменено в версии 3.5: Если системный вызов прерван и обработчик сигнала не вызывает исключение, метод теперь повторяет системный вызов вместо того, чтобы вызывать исключение InterruptedError (см. PEP 475 с обоснованием).

socket.recvfrom(bufsize[, flags])

Получает данные из сокета. Возвращает пару (bytes, address), где bytes – объект bytes с полученными данными, а address – адрес сокета, отправившего данные. Значение необязательного аргумента flags описано на странице руководства Unix recv(2); по умолчанию он равен нулю. (Формат address зависит от семейства адресов – см. выше.)

Изменено в версии 3.5: Если системный вызов прерван и обработчик сигнала не вызывает исключение, метод теперь повторяет системный вызов вместо того, чтобы вызывать исключение InterruptedError (см. PEP 475 с обоснованием).

socket.recvmsg(bufsize[, ancbufsize[, flags]])

Принимает обычные данные (до bufsize байт) и вспомогательные данные из сокета. Аргумент ancbufsize задаёт размер внутреннего буфера для приёма вспомогательных данных в байтах; по умолчанию равен 0, то есть вспомогательные данные приниматься не будут. Подходящие размеры буфера для вспомогательных данных можно вычислить с помощью CMSG_SPACE() или CMSG_LEN(); данные, не помещающиеся в буфер, могут быть усечены или отброшены. Аргумент flags по умолчанию равен 0 и имеет тот же смысл, что и для recv().

Возвращаемое значение – кортеж из 4 элементов: (data, ancdata, msg_flags, address). Элемент data – это объект bytes, содержащий принятые невспомогательные данные. Элемент ancdata – это список из нуля или более кортежей (cmsg_level, cmsg_type, cmsg_data), представляющих принятые вспомогательные данные (управляющие сообщения): cmsg_level и cmsg_type – целые числа, задающие уровень протокола и тип протокола соответственно, а cmsg_data – объект bytes с соответствующими данными. Элемент msg_flags – побитовое ИЛИ различных флагов, указывающих на состояние принятого сообщения; подробнее см. в системной документации. Если принимающий сокет не подключён, address – это адрес отправляющего сокета (если доступен); в противном случае его значение не определено.

В некоторых системах sendmsg() и recvmsg() можно использовать для передачи файловых дескрипторов между процессами через AF_UNIX-сокет. Когда этот механизм используется (он часто ограничен SOCK_STREAM-сокетами), recvmsg() вернет во вспомогательных данных элементы вида (socket.SOL_SOCKET, socket.SCM_RIGHTS, fds), где fds – это объект bytes, представляющий новые файловые дескрипторы в виде двоичного массива нативного типа C int. Если recvmsg() возбуждает исключение после возврата системного вызова, он сначала попытается закрыть все файловые дескрипторы, полученные через этот механизм.

Некоторые системы не указывают усечённую длину частично принятых вспомогательных данных. Если элемент, по-видимому, выходит за конец буфера, recvmsg() выдаст RuntimeWarning и вернёт ту его часть, которая находится в буфере, при условии, что она не была усечена до начала соответствующих данных.

В системах, поддерживающих механизм SCM_RIGHTS, следующая функция будет принимать до maxfds файловых дескрипторов, возвращая данные сообщения и список, содержащий дескрипторы (игнорируя неожиданные ситуации, такие как приём посторонних управляющих сообщений). См. также sendmsg().

import socket, array

def recv_fds(sock, msglen, maxfds):
    fds = array.array("i")   # Массив целых чисел
    msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(maxfds * fds.itemsize))
    for cmsg_level, cmsg_type, cmsg_data in ancdata:
        if (cmsg_level == socket.SOL_SOCKET and cmsg_type == socket.SCM_RIGHTS):
            # Добавить данные, игнорируя любые усечённые целые числа в конце.
            fds.fromstring(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)])
    return msg, list(fds)

Доступность: большинство платформ Unix, возможно, и другие.

Новое в версии 3.3.

Изменено в версии 3.5: Если системный вызов прерван и обработчик сигнала не вызывает исключение, метод теперь повторяет системный вызов вместо того, чтобы вызывать исключение InterruptedError (см. PEP 475 с обоснованием).

socket.recvmsg_into(buffers[, ancbufsize[, flags]])

Принимает обычные и вспомогательные данные из сокета, действуя как recvmsg(), но разбрасывает невспомогательные данные по нескольким буферам вместо возврата нового объекта bytes. Аргумент buffers должен быть итерируемым объектом, содержащим объекты, предоставляющие буферы для записи (например, объекты bytearray); они будут заполняться последовательными фрагментами невспомогательных данных, пока все данные не будут записаны или буферы не закончатся. Операционная система может установить ограничение (значение sysconf() SC_IOV_MAX) на количество используемых буферов. Аргументы ancbufsize и flags имеют тот же смысл, что и для recvmsg().

Возвращаемое значение – кортеж из 4 элементов: (nbytes, ancdata, msg_flags, address), где nbytes – общее количество байт невспомогательных данных, записанных в буферы, а ancdata, msg_flags и address такие же, как для recvmsg().

Пример:

>>> import socket
>>> s1, s2 = socket.socketpair()
>>> b1 = bytearray(b'----')
>>> b2 = bytearray(b'0123456789')
>>> b3 = bytearray(b'--------------')
>>> s1.send(b'Mary had a little lamb')
22
>>> s2.recvmsg_into([b1, memoryview(b2)[2:9], b3])
(22, [], 0, None)
>>> [b1, b2, b3]
[bytearray(b'Mary'), bytearray(b'01 had a 9'), bytearray(b'little lamb---')]

Доступность: большинство платформ Unix, возможно, и другие.

Новое в версии 3.3.

socket.recvfrom_into(buffer[, nbytes[, flags]])

Получает данные из сокета, записывая их в buffer вместо создания новой строки байтов. Возвращает пару (nbytes, address), где nbytes – количество полученных байтов, а address – адрес сокета, отправившего данные. Значение необязательного аргумента flags описано на странице руководства Unix recv(2); по умолчанию он равен нулю. (Формат address зависит от семейства адресов – см. выше.)

socket.recv_into(buffer[, nbytes[, flags]])

Получает из сокета до nbytes байтов, сохраняя данные в буфер, а не создавая новую строку байтов. Если nbytes не указан (или равен 0), принимает столько байтов, сколько помещается в переданный буфер. Возвращает количество полученных байтов. Значение необязательного аргумента flags описано на странице руководства Unix recv(2); по умолчанию он равен нулю.

socket.send(bytes[, flags])

Отправляет данные в сокет. Сокет должен быть подключён к удалённому сокету. Необязательный аргумент flags имеет тот же смысл, что и для recv() выше. Возвращает количество отправленных байтов. Приложения обязаны проверять, что все данные были отправлены; если передана только часть данных, приложение должно попытаться отправить оставшиеся. Дополнительную информацию по этой теме можно найти в Socket Programming HOWTO.

Изменено в версии 3.5: Если системный вызов прерван и обработчик сигнала не вызывает исключение, метод теперь повторяет системный вызов вместо того, чтобы вызывать исключение InterruptedError (см. PEP 475 с обоснованием).

socket.sendall(bytes[, flags])

Отправляет данные в сокет. Сокет должен быть подключён к удалённому сокету. Необязательный аргумент flags имеет тот же смысл, что и для recv() выше. В отличие от send(), этот метод продолжает отправлять данные из bytes, пока не будут отправлены все данные или не произойдёт ошибка. При успехе возвращается None. В случае ошибки выбрасывается исключение, и невозможно определить, сколько данных, если вообще, было успешно отправлено.

Изменено в версии 3.5: Тайм-аут сокета больше не сбрасывается при каждой успешной отправке данных. Теперь тайм-аут сокета – это максимальная общая продолжительность для отправки всех данных.

Изменено в версии 3.5: Если системный вызов прерван и обработчик сигнала не вызывает исключение, метод теперь повторяет системный вызов вместо того, чтобы вызывать исключение InterruptedError (см. PEP 475 с обоснованием).

socket.sendto(bytes, address)
socket.sendto(bytes, flags, address)

Отправляет данные в сокет. Сокет не должен быть подключён к удалённому сокету, поскольку целевой сокет задаётся параметром address. Необязательный аргумент flags имеет тот же смысл, что и для recv() выше. Возвращает количество отправленных байтов. (Формат address зависит от семейства адресов – см. выше.)

Изменено в версии 3.5: Если системный вызов прерван и обработчик сигнала не вызывает исключение, метод теперь повторяет системный вызов вместо того, чтобы вызывать исключение InterruptedError (см. PEP 475 с обоснованием).

socket.sendmsg(buffers[, ancdata[, flags[, address]]])

Отправляет обычные и вспомогательные данные в сокет, собирая невспомогательные данные из серии буферов и объединяя их в одно сообщение. Аргумент buffers задаёт невспомогательные данные как итерируемый объект из bytes-подобных объектов (например, объекты bytes); операционная система может установить ограничение (значение sysconf() SC_IOV_MAX) на количество буферов, которые можно использовать. Аргумент ancdata задаёт вспомогательные данные (управляющие сообщения) как итерируемый объект из нуля или более кортежей (cmsg_level, cmsg_type, cmsg_data), где cmsg_level и cmsg_type – целые числа, определяющие уровень протокола и тип протокола соответственно, а cmsg_data – bytes-подобный объект, содержащий соответствующие данные. Обратите внимание, что некоторые системы (в частности, системы без CMSG_SPACE()) могут поддерживать отправку только одного управляющего сообщения за вызов. Аргумент flags по умолчанию равен 0 и имеет то же значение, что и для send(). Если address указан и не равен None, он устанавливает адрес назначения для сообщения. Возвращаемое значение – количество отправленных байтов невспомогательных данных.

Следующая функция отправляет список файловых дескрипторов fds через сокет AF_UNIX в системах, поддерживающих механизм SCM_RIGHTS. См. также recvmsg().

import socket, array

def send_fds(sock, msg, fds):
    return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS, array.array("i", fds))])

Доступность: большинство платформ Unix, возможно, и другие.

Новое в версии 3.3.

Изменено в версии 3.5: Если системный вызов прерван и обработчик сигнала не вызывает исключение, метод теперь повторяет системный вызов вместо того, чтобы вызывать исключение InterruptedError (см. PEP 475 с обоснованием).

socket.sendfile(file, offset=0, count=None)

Отправляет файл до достижения EOF, используя высокопроизводительный os.sendfile, и возвращает общее количество отправленных байтов. file должен быть обычным файловым объектом, открытым в двоичном режиме. Если os.sendfile недоступен (например, в Windows) или file не является обычным файлом, вместо него будет использован send(). offset указывает, откуда начинать чтение файла. Если указан, count – это общее количество байтов для передачи, в отличие от отправки файла до EOF. Позиция файла обновляется при возврате, а также в случае ошибки, и тогда file.tell() можно использовать для определения количества отправленных байтов. Сокет должен быть типа SOCK_STREAM. Неблокирующие сокеты не поддерживаются.

Новое в версии 3.5.

socket.set_inheritable(inheritable)

Устанавливает флаг наследования файлового дескриптора сокета или дескриптора сокета.

Новое в версии 3.4.

socket.setblocking(flag)

Устанавливает блокирующий или неблокирующий режим сокета: если flag равен false, сокет переводится в неблокирующий режим, иначе в блокирующий.

Этот метод является сокращённой записью для определённых вызовов settimeout():

  • sock.setblocking(True) эквивалентен sock.settimeout(None)
  • sock.setblocking(False) эквивалентен sock.settimeout(0.0)
socket.settimeout(value)

Устанавливает тайм-аут для блокирующих операций с сокетом. Аргумент value может быть неотрицательным числом с плавающей запятой, задающим секунды, или None. Если задано ненулевое значение, последующие операции с сокетом будут вызывать исключение timeout, если время тайм-аута value истекло до завершения операции. Если задан ноль, сокет переводится в неблокирующий режим. Если задан None, сокет переводится в блокирующий режим.

Для получения дополнительной информации обратитесь к заметкам о тайм-аутах сокетов.

socket.setsockopt(level, optname, value)

Устанавливает значение указанной опции сокета (см. справочную страницу Unix setsockopt(2)). Необходимые символические константы определены в модуле socket (SO_* и др.). Значение может быть целым числом или объектом, подобным байтам, представляющим буфер. Во втором случае вызывающий код должен сам позаботиться о том, чтобы байтовая строка содержала корректные биты (см. опциональный встроенный модуль struct для способа кодирования C-структур в байтовые строки).

Изменено в версии 3.5: Теперь принимается записываемый байтоподобный объект.

socket.shutdown(how)

Завершает одну или обе половины соединения. Если how равен SHUT_RD, дальнейшие приёмы запрещены. Если how равен SHUT_WR, дальнейшие отправки запрещены. Если how равен SHUT_RDWR, дальнейшие отправки и приёмы запрещены.

socket.share(process_id)

Дублирует сокет и подготавливает его для совместного использования с целевым процессом. Целевому процессу должен быть предоставлен идентификатор process_id. Полученный bytes-объект затем может быть передан целевому процессу с помощью какой-либо формы межпроцессного взаимодействия, и сокет может быть воссоздан там с помощью fromshare(). После вызова этого метода сокет можно безопасно закрыть, так как операционная система уже продублировала его для целевого процесса.

Доступность: Windows.

Новое в версии 3.3.

Обратите внимание, что методы read() и write() отсутствуют; вместо них используйте recv() и send() без аргумента flags.

Объекты сокетов также имеют следующие (только для чтения) атрибуты, соответствующие значениям, переданным конструктору socket.

socket.family

Семейство сокета.

socket.type

Тип сокета.

socket.proto

Протокол сокета.

18.1.4. Замечания по тайм-аутам сокетовNotes on socket timeouts

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

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

Примечание

На уровне операционной системы сокеты в режиме тайм-аута внутренне устанавливаются в неблокирующий режим. Кроме того, блокирующий режим и режим тайм-аута разделяются между файловыми дескрипторами и объектами сокетов, относящимися к одной сетевой конечной точке. Эта деталь реализации может иметь заметные последствия, если, например, вы решите использовать fileno() сокета.

18.1.4.1. Тайм-ауты и метод connectTimeouts and the connect method

Операция connect() также подчиняется настройке тайм-аута, и в целом рекомендуется вызывать settimeout() перед вызовом connect() или передавать параметр тайм-аута в create_connection(). Однако сетевая подсистема системы также может вернуть собственную ошибку тайм-аута соединения независимо от любых настроек тайм-аута сокета Python.

18.1.4.2. Тайм-ауты и метод acceptTimeouts and the accept method

Если getdefaulttimeout() не равно None, сокеты, возвращаемые методом accept(), наследуют этот тайм-аут. В противном случае поведение зависит от настроек слушающего сокета:

  • если слушающий сокет находится в блокирующем режиме или в режиме тайм-аута, то сокет, возвращаемый accept(), находится в блокирующем режиме;
  • если слушающий сокет находится в неблокирующем режиме, то будет ли сокет, возвращаемый accept(), в блокирующем или неблокирующем режиме, зависит от операционной системы. Если вы хотите обеспечить кроссплатформенное поведение, рекомендуется вручную переопределить этот параметр.

18.1.5. ПримерExample

Вот четыре минимальных примера программ, использующих протокол TCP/IP: сервер, который отправляет обратно все полученные данные (обслуживая только одного клиента), и использующий его клиент. Обратите внимание, что сервер должен выполнить последовательность socket(), bind(), listen(), accept() (возможно, повторяя accept() для обслуживания более одного клиента), в то время как клиенту нужна только последовательность socket(), connect(). Также обратите внимание, что сервер не вызывает sendall()/recv() на сокете, который слушает, а на новом сокете, возвращённом accept().

Первые два примера поддерживают только IPv4.

# Программа эхо-сервера
import socket

HOST = ''                 # Символическое имя, обозначающее все доступные интерфейсы
PORT = 50007              # Произвольный непривилегированный порт
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data: break
            conn.sendall(data)
# Программа эхо-клиента
import socket

HOST = 'daring.cwi.nl'    # Удалённый хост
PORT = 50007              # Тот же порт, что и у сервера
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(1024)
print('Received', repr(data))

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

# Программа эхо-сервера
import socket
import sys

HOST = None               # Символическое имя, обозначающее все доступные интерфейсы
PORT = 50007              # Произвольный непривилегированный порт
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                              socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except OSError as msg:
        s = None
        continue
    try:
        s.bind(sa)
        s.listen(1)
    except OSError as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print('could not open socket')
    sys.exit(1)
conn, addr = s.accept()
with conn:
    print('Connected by', addr)
    while True:
        data = conn.recv(1024)
        if not data: break
        conn.send(data)
# Программа эхо-клиента
import socket
import sys

HOST = 'daring.cwi.nl'    # Удалённый хост
PORT = 50007              # Тот же порт, что и у сервера
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except OSError as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except OSError as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print('could not open socket')
    sys.exit(1)
with s:
    s.sendall(b'Hello, world')
    data = s.recv(1024)
print('Received', repr(data))

Следующий пример показывает, как написать очень простой снифер сети с помощью сырых сокетов в Windows. Для изменения интерфейса пример требует прав администратора:

import socket

# общедоступный сетевой интерфейс
HOST = socket.gethostbyname(socket.gethostname())

# создать сырой сокет и привязать его к общедоступному интерфейсу
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))

# Включать IP-заголовки
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# принять все пакеты
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

# принять пакет
print(s.recvfrom(65565))

# неразборчивый режим отключён
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

Последний пример показывает, как использовать интерфейс сокетов для обмена данными с сетью CAN с помощью протокола сырых сокетов. Чтобы вместо этого использовать CAN с протоколом широковещательного менеджера, откройте сокет:

socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_BCM)

После привязки (CAN_RAW) или подключения (CAN_BCM) сокета можно использовать операции socket.send() и socket.recv() (и их аналоги) с объектом сокета как обычно.

Для этого примера могут потребоваться особые привилегии:

import socket
import struct


# Упаковка/распаковка CAN-фреймов (см. 'struct can_frame' в <linux/can.h>)

can_frame_fmt = "=IB3x8s"
can_frame_size = struct.calcsize(can_frame_fmt)

def build_can_frame(can_id, data):
    can_dlc = len(data)
    data = data.ljust(8, b'\x00')
    return struct.pack(can_frame_fmt, can_id, can_dlc, data)

def dissect_can_frame(frame):
    can_id, can_dlc, data = struct.unpack(can_frame_fmt, frame)
    return (can_id, can_dlc, data[:can_dlc])


# создать сырой сокет и привязать его к интерфейсу 'vcan0'
s = socket.socket(socket.AF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
s.bind(('vcan0',))

while True:
    cf, addr = s.recvfrom(can_frame_size)

    print('Received: can_id=%x, can_dlc=%x, data=%s' % dissect_can_frame(cf))

    try:
        s.send(cf)
    except OSError:
        print('Error sending CAN frame')

    try:
        s.send(build_can_frame(0x01, b'\x01\x02\x03'))
    except OSError:
        print('Error sending CAN frame')

Запуск примера несколько раз со слишком маленькой задержкой между выполнениями может привести к этой ошибке:

OSError: [Errno 98] Address already in use

Это связано с тем, что предыдущее выполнение оставило сокет в состоянии TIME_WAIT, и его нельзя сразу использовать повторно.

Существует флаг socket, который можно установить, чтобы предотвратить это, socket.SO_REUSEADDR:

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))

Флаг SO_REUSEADDR указывает ядру переиспользовать локальный сокет в состоянии TIME_WAIT, не дожидаясь истечения его естественного тайм-аута.

См. также

Для ознакомления с программированием сокетов (на C) см. следующие статьи:

  • Вводное руководство по межпроцессному взаимодействию в 4.3BSD, Стюарт Сечрест
  • Продвинутое руководство по межпроцессному взаимодействию в 4.3BSD, Сэмюэл Дж. Леффлер и др.

Оба находятся в UNIX Programmer’s Manual, Supplementary Documents 1 (разделы PS1:7 и PS1:8). Справочные материалы по сокетным системным вызовам для конкретных платформ также являются ценным источником информации о деталях семантики сокетов. Для Unix обращайтесь к страницам руководства; для Windows – к спецификации WinSock (или Winsock 2). Для API с поддержкой IPv6 читателю может быть полезно обратиться к RFC 3493 под названием Basic Socket Interface Extensions for IPv6.