Spec-Zone.ru › Python 3.5

socket — Интерфейс сетевого взаимодействия низкого уровня

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

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

Примечание

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

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

См. также

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

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

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

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

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

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

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

  • Для семейства адресов AF_INET используется пара (host, port), где host — строка, представляющая либо имя хоста в формате доменных имен интернета, например, 'daring.cwi.nl', либо IPv4-адрес, например, '100.50.200.5', а port — целое число.
  • Для семейства адресов AF_INET6 используется четвёрка (host, port, flowinfo, scopeid), где flowinfo и scopeid представляют члены struct sockaddr_in6 в C. Для методов модуля socket flowinfo и scopeid могут быть опущены только для обратной совместимости. Тем не менее, пропуск scopeid может вызвать проблемы при работе со скопированными 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.

    Новое в версии 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.

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

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

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

2. Содержимое модуля

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

2.1. Исключения

exception socket.error

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

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

exception socket.herror

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

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

exception socket.gaierror

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

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

exception socket.timeout

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

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

2.2. Константы

Константы 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, также определены в модуле сокетов. Они обычно используются в аргументах к методам setsockopt() и getsockopt() объектов сокета. В большинстве случаев определяются только те символы, которые определены в заголовочных файлах Unix; для некоторых символов предоставляются значения по умолчанию.

socket.AF_CAN
socket.PF_CAN
SOL_CAN_*
CAN_*

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

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

Добавлено в версии 3.3.

socket.CAN_BCM
CAN_BCM_*

CAN_BCM в семействе протоколов CAN — протокол менеджера широковещательной передачи (BCM). Константы менеджера широковещательной передачи, документированные в документации Linux, также определены в модуле сокетов.

Доступность: 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, также определены в модуле сокетов.

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

Добавлено в версии 3.3.

SIO_*
RCVALL_*

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

TIPC_*

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

socket.AF_LINK

Доступность: 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.

2.3. Функции

2.3.1. Создание сокетов

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

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-сервису, прослушивающему по интернет-адресу (кортеж 2-элементов (host, port)), и вернуть объект сокета. Эта функция более высокого уровня, чем socket.connect(): если host — имя хоста, не являющееся числом, оно будет пытаться разрешить его для AF_INET и AF_INET6, а затем попытаться подключиться ко всем возможным адресам по очереди, пока подключение не будет выполнено успешно. Это упрощает написание клиентов, совместимых как с IPv4, так и с IPv6.

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

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

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

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

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

Созданный сокет не наследуется.

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

socket.fromshare(data)

Инициализировать сокет из данных, полученных от метода socket.share(). Предполагается, что сокет находится в режиме блокировки.

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

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

socket.SocketType

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

2.3.2. Другие функции

Модуль 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 будет строкой, представляющей каноническое имя host, если AI_CANONNAME является частью аргумента flags; в противном случае canonname будет пустой. sockaddr — кортеж, описывающий адрес сокета, формат которого зависит от возвращаемого family (кортеж 2-элементов для AF_INET, кортеж 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, и следует использовать getaddrinfo() для поддержки стека IPv4/v6.

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 в кортеж из 2 элементов (host, port). В зависимости от настроек flags, результат может содержать полное доменное имя или числовое представление адреса в host. Аналогично, port может содержать строчное имя порта или числовой номер порта.

socket.getprotobyname(protocolname)

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

socket.getservbyname(servicename[, protocolname])

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

socket.getservbyport(port[, protocolname])

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

socket.ntohl(x)

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

socket.ntohs(x)

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

socket.htonl(x)

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

socket.htons(x)

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

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, и inet_pton() следует использовать вместо для поддержки стека IPv4/v6.

socket.inet_ntoa(packed_ip)

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

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

Изменено в версии 3.5: Теперь принимается изменяемый bytes-like object.

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-like object некоторого количества байтов) в стандартное семейно-специфическое строковое представление (например, '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: Теперь принимается изменяемый bytes-like object.

END_OF_DOCUMENT_MARKER
socket.CMSG_LEN(length)

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

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

Добавлена в версии 3.3.

socket.CMSG_SPACE(length)

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

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

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

Добавлена в версии 3.3.

socket.getdefaulttimeout()

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

socket.setdefaulttimeout(timeout)

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

socket.sethostname(name)

Устанавливает имя хоста машины на name. Это вызовет OSError, если у вас недостаточно прав.

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

Добавлена в версии 3.3.

socket.if_nameindex()

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

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

Добавлена в версии 3.3.

socket.if_nametoindex(if_name)

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

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

Добавлена в версии 3.3.

socket.if_indextoname(if_index)

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

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

Добавлена в версии 3.3.

3. Объекты сокетов

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

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

socket.accept()

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

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

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

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

socket.bind(address)

Связывает сокет с адресом. Сокет не должен быть уже связан (формат адреса зависит от семейства адресов — см. выше).

socket.close()

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

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

Примечание

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

socket.connect(address)

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

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

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

socket.connect_ex(address)

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

socket.detach()

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

Добавлена в версии 3.2.

socket.dup()

Создает дубликат сокета.

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

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

socket.fileno()

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

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

socket.get_inheritable()

Получает флаг наследуемости дескриптора файла сокета или дескриптора сокета: 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(), за исключением того, что поддерживаются только значения mode: '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, представляющий новые дескрипторы файлов в виде двоичного массива типа int C. Если recvmsg() вызывает исключение после возврата системного вызова, она сначала попытается закрыть все дескрипторы файлов, полученные с помощью этого механизма.

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

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

import socket, array

def recv_fds(sock, msglen, maxfds):
    fds = array.array("i")   # Array of ints
    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):
            # Append data, ignoring any truncated integers at the end.
            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 вместо создания новой строки bytes. Значение возврата — пара (nbytes, address), где nbytes — количество полученных байтов, а address — адрес сокета, отправляющего данные. См. страницу руководства Unix recv(2) для понимания необязательного аргумента flags; по умолчанию он равен нулю. (Формат address зависит от семейства адресов — см. выше.)

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

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

socket.send(bytes[, flags])

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

Изменено в версии 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 для обоснования).

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

Отправка обычных и дополнительных данных на сокет, собирая не-дополнительные данные из серии буферов и объединяя их в одно сообщение. Аргумент buffers указывает не-дополнительные данные как итерируемый объект объектов типа байт (например, bytes объекты); операционная система может установить ограничение (sysconf() значение SC_IOV_MAX) на количество используемых буферов. Аргумент ancdata указывает дополнительные данные (сообщения управления) как итерируемый объект нуля или более кортежей (cmsg_level, cmsg_type, cmsg_data), где cmsg_level и cmsg_type — целые числа, определяющие уровень протокола и тип, специфичный для протокола соответственно, а cmsg_data — объект типа байт, содержащий связанные данные. Обратите внимание, что некоторые системы (в частности, системы без 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)

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

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

socket.set_inheritable(inheritable)

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

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

socket.setblocking(flag)

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

Этот метод является сокращением для определенных вызовов 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. Результирующий объект типа байт можно передать целевому процессу с помощью какой-либо межпроцессной связи, и сокет можно воссоздать там с помощью fromshare(). После вызова этого метода можно безопасно закрыть сокет, так как операционная система уже продублировала его для целевого процесса.

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

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

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

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

socket.family

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

socket.type

Тип сокета.

socket.proto

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

4. Примечания по таймаутам сокетов

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

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

Примечание

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

4.1. Таймауты и метод connect

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

4.2. Таймауты и метод accept

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

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

5. Пример

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

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

# Echo server program
import socket

HOST = ''                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
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)
# Echo client program
import socket

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
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-трафик. Сторона клиента попытается подключиться ко всем адресам, полученным в результате разрешения имени, и отправит трафик первому успешно подключившемуся.

# Echo server program
import socket
import sys

HOST = None               # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
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)
# Echo client program
import socket
import sys

HOST = 'daring.cwi.nl'    # The remote host
PORT = 50007              # The same port as used by the server
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

# the public network interface
HOST = socket.gethostbyname(socket.gethostname())

# create a raw socket and bind it to the public interface
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind((HOST, 0))

# Include IP headers
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)

# receive all packages
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

# receive a package
print(s.recvfrom(65565))

# disabled promiscuous mode
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 frame packing/unpacking (see 'struct can_frame' in <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])


# create a raw socket and bind it to the 'vcan0' interface
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, дополнительные документы 1 (разделы PS1:7 и PS1:8). Платформенно-специфические справочные материалы по различным системным вызовам, связанным с сокетами, также являются ценным источником информации о деталях семантики сокетов. Для Unix см. страницы руководства; для Windows см. спецификацию WinSock (или Winsock 2). Для IPv6-совместимых API пользователи могут обратиться к RFC 3493 с названием "Основные расширения интерфейса сокетов для IPv6".

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/socket.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API