> **Источник:** https://python-all.ru/3.1/library/socket.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 17.2. `socket` – Низкоуровневый сетевой интерфейс

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

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

Интерфейс Python представляет собой прямую трансляцию системных вызовов и библиотечного интерфейса сокетов Unix в объектно-ориентированном стиле Python: функция [`socket()`](https://python-all.ru/3.1/library/socket.html#socket.socket) возвращает *объект сокета*, методы которого реализуют различные системные вызовы сокетов. Типы параметров находятся на более высоком уровне, чем в интерфейсе C: как и при операциях `read()` и `write()` с файлами Python, выделение буфера при приёме происходит автоматически, а длина буфера при отправке подразумевается неявно.

> **См. также**
>
> **Модуль [`socketserver`](https://python-all.ru/3.1/library/socketserver.html#module-socketserver)**
>
> Классы, упрощающие написание сетевых серверов.
>
> **Модуль [`ssl`](https://python-all.ru/3.1/library/ssl.html#module-ssl)**
>
> Обёртка TLS/SSL для объектов сокетов.

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

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

Адреса сокетов представляются следующим образом:

- Для семейства адресов [`AF_UNIX`](https://python-all.ru/3.1/library/socket.html#socket.AF_UNIX) используется одна строка.
- Пара `(host, port)` используется для семейства адресов [`AF_INET`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET), где *host* – строка, представляющая либо имя хоста в доменной нотации Интернета, например `'daring.cwi.nl'`, либо IPv4-адрес, например `'100.50.200.5'`, а *port* – целочисленный номер порта.
- Для семейства адресов [`AF_INET6`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET6) используется четырехэлементный кортеж `(host, port, flowinfo, scopeid)`, где *flowinfo* и *scopeid* представляют собой поля `sin6_flowinfo` и `sin6_scope_id` в структуре `struct sockaddr_in6` на языке C. Для методов модуля `socket`, *flowinfo* и *scopeid* могут быть опущены только для обратной совместимости. Однако обратите внимание, что пропуск *scopeid* может вызвать проблемы при работе с адресами IPv6 с областью действия (scoped).
- Сокеты `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* – ссылка (reference), а *v3* должно быть установлено в 0.

    Если *addr\_type* равно TIPC\_ADDR\_ID, то *v1* – это узел, *v2* – ссылка (reference), а *v3* должно быть установлено в 0.
- Некоторые другие семейства адресов (`AF_BLUETOOTH`, `AF_PACKET`) поддерживают особые представления.

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

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

Все ошибки возбуждают исключения. Обычные исключения для недопустимых типов аргументов и нехватки памяти могут быть возбуждены; ошибки, связанные с семантикой сокета или адреса, возбуждают [`socket.error`](https://python-all.ru/3.1/library/socket.html#socket.error) или один из его подклассов.

Неподдерживаемый режим поддерживается через [`setblocking()`](https://python-all.ru/3.1/library/socket.html#socket.socket.setblocking). Более общий подход на основе тайм-аутов поддерживается через [`settimeout()`](https://python-all.ru/3.1/library/socket.html#socket.socket.settimeout).

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

Модуль `socket` экспортирует следующие константы и функции:

#### `exception socket.error`

Это исключение возникает при ошибках, связанных с сокетами. Сопутствующее значение – либо строка с описанием ошибки, либо пара `(errno, string)`, представляющая ошибку, возвращенную системным вызовом, аналогично значению, сопутствующему [`os.error`](https://python-all.ru/3.1/library/os.html#os.error). См. модуль [`errno`](https://python-all.ru/3.1/library/errno.html#module-errno), который содержит имена для кодов ошибок, определенных базовой операционной системой.

#### `exception socket.herror`

Это исключение возникает при ошибках, связанных с адресами, т.е. для функций, использующих *h\_errno* в C API, включая [`gethostbyname_ex()`](https://python-all.ru/3.1/library/socket.html#socket.gethostbyname_ex) и [`gethostbyaddr()`](https://python-all.ru/3.1/library/socket.html#socket.gethostbyaddr).

Сопутствующее значение – это пара `(h_errno, string)`, представляющая ошибку, возвращенную библиотечным вызовом. *string* представляет описание *h\_errno*, как возвращено функцией `hstrerror()` языка C.

#### `exception socket.gaierror`

Это исключение возникает при ошибках, связанных с адресами, для

[`getaddrinfo()`](https://python-all.ru/3.1/library/socket.html#socket.getaddrinfo)

и

[`getnameinfo()`](https://python-all.ru/3.1/library/socket.html#socket.getnameinfo)

. Сопутствующее значение – это пара

`(error, string)`

, представляющая ошибку, возвращенную библиотечным вызовом.

*string*

представляет описание

*error*

, как возвращено функцией

`gai_strerror()`

языка C. Значение

*error*

будет соответствовать одной из констант

`EAI_*`

, определенных в этом модуле.

#### `exception socket.timeout`

Это исключение возникает при тайм-ауте на сокете, для которого тайм-ауты были включены предшествующим вызовом

[`settimeout()`](https://python-all.ru/3.1/library/socket.html#socket.socket.settimeout)

. Сопутствующее значение – это строка, которая в настоящее время всегда равна «timed out».

#### `socket.AF_UNIX`

#### `socket.AF_INET`

#### `socket.AF_INET6`

Эти константы представляют семейства адресов (и протоколов), используемые для первого аргумента

[`socket()`](https://python-all.ru/3.1/library/socket.html#socket.socket)

. Если константа

[`AF_UNIX`](https://python-all.ru/3.1/library/socket.html#socket.AF_UNIX)

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

#### `socket.SOCK_STREAM`

#### `socket.SOCK_DGRAM`

#### `socket.SOCK_RAW`

#### `socket.SOCK_RDM`

#### `socket.SOCK_SEQPACKET`

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

[`socket()`](https://python-all.ru/3.1/library/socket.html#socket.socket)

. В зависимости от системы могут быть доступны дополнительные константы. (Обычно полезными считаются только

[`SOCK_STREAM`](https://python-all.ru/3.1/library/socket.html#socket.SOCK_STREAM)

и

[`SOCK_DGRAM`](https://python-all.ru/3.1/library/socket.html#socket.SOCK_DGRAM)

.)

#### `SO_*`

#### `socket.SOMAXCONN`

#### `MSG_*`

#### `SOL_*`

#### `IPPROTO_*`

#### `IPPORT_*`

#### `INADDR_*`

#### `IP_*`

#### `IPV6_*`

#### `EAI_*`

#### `AI_*`

#### `NI_*`

#### `TCP_*`

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

`setsockopt()`

и

`getsockopt()`

объектов сокетов. В большинстве случаев определены только те символы, которые есть в заголовочных файлах Unix; для некоторых символов заданы значения по умолчанию.

#### `SIO_*`

#### `RCVALL_*`

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

`ioctl()`

объектов сокетов.

#### `TIPC_*`

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

#### `socket.has_ipv6`

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

#### `socket.create_connection(address[, timeout])`

Вспомогательная функция. Подключается к

*address*

(кортеж из двух элементов

`(host, port)`

) и возвращает объект сокета. Передача необязательного параметра

*timeout*

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

*timeout*

не указан, используется глобальная настройка тайм-аута по умолчанию, возвращаемая

[`getdefaulttimeout()`](https://python-all.ru/3.1/library/socket.html#socket.getdefaulttimeout)

.

#### `socket.getaddrinfo(host, port, family=0, socktype=0, proto=0, flags=0)`

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

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

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

`(family, socktype, proto, canonname, sockaddr)`

В этих кортежах *family*, *socktype* и *proto* – целые числа, и их следует передавать функции [`socket()`](https://python-all.ru/3.1/library/socket.html#socket.socket). *canonname* будет строкой, представляющей каноническое имя узла *host*, если `AI_CANONNAME` входит в аргумент *flags*; в противном случае *canonname* будет пустой строкой. *sockaddr* – это кортеж, описывающий адрес сокета; его формат зависит от возвращённого *family* (двухэлементный кортеж `(address, port)` для [`AF_INET`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET), четырёхэлементный кортеж `(address, port, flow info, scope id)` для [`AF_INET6`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET6)). Этот кортеж предназначен для передачи методу [`socket.connect()`](https://python-all.ru/3.1/library/socket.html#socket.socket.connect).

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

```python
>>> socket.getaddrinfo("www.python.org", 80, 0, 0, socket.SOL_TCP)
[(2, 1, 6, '', ('82.94.164.162', 80)),
 (10, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0))]
```

#### `socket.getfqdn([name])`

Возвращает полное доменное имя для

*name*

. Если

*name*

опущен или пуст, он интерпретируется как локальный хост. Чтобы найти полное имя, проверяется имя хоста, возвращённое

[`gethostbyaddr()`](https://python-all.ru/3.1/library/socket.html#socket.gethostbyaddr)

, а затем, при наличии, псевдонимы хоста. Выбирается первое имя, содержащее точку. Если полное доменное имя недоступно, возвращается имя хоста, полученное через

[`gethostname()`](https://python-all.ru/3.1/library/socket.html#socket.gethostname)

.

#### `socket.gethostbyname(hostname)`

Преобразует имя хоста в формат IPv4-адреса. IPv4-адрес возвращается в виде строки, например

`'100.50.200.5'`

. Если само имя хоста является IPv4-адресом, оно возвращается без изменений. См.

[`gethostbyname_ex()`](https://python-all.ru/3.1/library/socket.html#socket.gethostbyname_ex)

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

[`gethostbyname()`](https://python-all.ru/3.1/library/socket.html#socket.gethostbyname)

не поддерживает разрешение имён IPv6, поэтому для поддержки dual stack IPv4/v6 следует использовать

[`getaddrinfo()`](https://python-all.ru/3.1/library/socket.html#socket.getaddrinfo)

.

#### `socket.gethostbyname_ex(hostname)`

Преобразует имя хоста в формат IPv4-адреса, расширенный интерфейс. Возвращает тройку

`(hostname, aliaslist, ipaddrlist)`

, где

*hostname*

– основное имя хоста, отвечающего на заданный

*ip\_address*

,

*aliaslist*

– (возможно, пустой) список альтернативных имён хоста для того же адреса, а

*ipaddrlist*

– список IPv4-адресов того же интерфейса на том же хосте (часто, но не всегда, один адрес).

[`gethostbyname_ex()`](https://python-all.ru/3.1/library/socket.html#socket.gethostbyname_ex)

не поддерживает разрешение имён IPv6, поэтому для поддержки dual stack IPv4/v6 следует использовать

[`getaddrinfo()`](https://python-all.ru/3.1/library/socket.html#socket.getaddrinfo)

.

#### `socket.gethostname()`

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

Если нужно узнать IP-адрес текущей машины, можно использовать `gethostbyname(gethostname())`. Эта операция предполагает, что существует корректное отображение адреса на хост, и это предположение выполняется не всегда.

Примечание: [`gethostname()`](https://python-all.ru/3.1/library/socket.html#socket.gethostname) не всегда возвращает полное доменное имя; используйте `getfqdn()` (см. выше).

#### `socket.gethostbyaddr(ip_address)`

Возвращает тройку

`(hostname, aliaslist, ipaddrlist)`

, где

*hostname*

– основное имя хоста, отвечающего на заданный

*ip\_address*

,

*aliaslist*

– (возможно, пустой) список альтернативных имён хоста для того же адреса, а

*ipaddrlist*

– список IPv4/v6-адресов того же интерфейса на том же хосте (скорее всего, содержащий только один адрес). Чтобы найти полное доменное имя, используйте функцию

[`getfqdn()`](https://python-all.ru/3.1/library/socket.html#socket.getfqdn)

.

[`gethostbyaddr()`](https://python-all.ru/3.1/library/socket.html#socket.gethostbyaddr)

поддерживает как IPv4, так и IPv6.

#### `socket.getnameinfo(sockaddr, flags)`

Преобразует адрес сокета

*sockaddr*

в кортеж из двух элементов

`(host, port)`

. В зависимости от настроек

*flags*

результат может содержать полное доменное имя или числовое представление адреса в

*host*

. Аналогично,

*port*

может содержать строковое имя порта или числовой номер порта.

#### `socket.getprotobyname(protocolname)`

Преобразует имя интернет-протокола (например,

`'icmp'`

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

[`socket()`](https://python-all.ru/3.1/library/socket.html#socket.socket)

. Обычно это требуется только для сокетов, открытых в «сыром» режиме (

[`SOCK_RAW`](https://python-all.ru/3.1/library/socket.html#socket.SOCK_RAW)

); для обычных режимов сокета правильный протокол выбирается автоматически, если протокол опущен или равен нулю.

#### `socket.getservbyname(servicename[, protocolname])`

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

`'tcp'`

или

`'udp'`

, в противном случае подойдёт любой протокол.

#### `socket.getservbyport(port[, protocolname])`

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

`'tcp'`

или

`'udp'`

, иначе подойдет любой протокол.

#### `socket.socket([family[, type[, proto]]])`

Создаёт новый сокет с заданным семейством адресов, типом сокета и номером протокола. Семейство адресов должно быть

[`AF_INET`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET)

(по умолчанию),

[`AF_INET6`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET6)

или

[`AF_UNIX`](https://python-all.ru/3.1/library/socket.html#socket.AF_UNIX)

. Тип сокета должен быть

[`SOCK_STREAM`](https://python-all.ru/3.1/library/socket.html#socket.SOCK_STREAM)

(по умолчанию),

[`SOCK_DGRAM`](https://python-all.ru/3.1/library/socket.html#socket.SOCK_DGRAM)

или, возможно, одна из констант

`SOCK_`

. Номер протокола обычно равен нулю и в этом случае может быть опущен.

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

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

[`socket()`](https://python-all.ru/3.1/library/socket.html#socket.socket)

выше. Семейство по умолчанию –

[`AF_UNIX`](https://python-all.ru/3.1/library/socket.html#socket.AF_UNIX)

, если оно определено на платформе; в противном случае по умолчанию используется

[`AF_INET`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET)

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

#### `socket.fromfd(fd, family, type[, proto])`

Дублирует файловый дескриптор

*fd*

(целое число, возвращаемое методом

`fileno()`

файлового объекта) и создаёт из результата объект сокета. Семейство адресов, тип сокета и номер протокола – как у функции

[`socket()`](https://python-all.ru/3.1/library/socket.html#socket.socket)

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

#### `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()`](https://python-all.ru/3.1/library/socket.html#socket.inet_aton) также принимает строки с менее чем тремя точками; подробнее см. в руководстве Unix *inet(3)*.

Если строка IPv4-адреса, переданная в эту функцию, недействительна, возбуждается [`socket.error`](https://python-all.ru/3.1/library/socket.html#socket.error). Обратите внимание, что точное определение допустимости зависит от реализации функции `inet_aton()` на C.

[`inet_aton()`](https://python-all.ru/3.1/library/socket.html#socket.inet_aton) не поддерживает IPv6, и для поддержки двойного стека IPv4/IPv6 вместо него следует использовать [`inet_pton()`](https://python-all.ru/3.1/library/socket.html#socket.inet_pton).

#### `socket.inet_ntoa(packed_ip)`

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

Если длина переданной этой функции последовательности байтов не равна ровно 4 байтам, возбуждается [`socket.error`](https://python-all.ru/3.1/library/socket.html#socket.error). [`inet_ntoa()`](https://python-all.ru/3.1/library/socket.html#socket.inet_ntoa) не поддерживает IPv6, поэтому для поддержки двойного стека IPv4/IPv6 следует использовать [`inet_ntop()`](https://python-all.ru/3.1/library/socket.html#socket.inet_ntop).

#### `socket.inet_pton(address_family, ip_string)`

Преобразует IP-адрес из строкового формата, зависящего от семейства, в упакованный двоичный формат. [`inet_pton()`](https://python-all.ru/3.1/library/socket.html#socket.inet_pton) полезен, когда библиотека или сетевой протокол требует объект типа `struct in_addr` (аналогично [`inet_aton()`](https://python-all.ru/3.1/library/socket.html#socket.inet_aton)) или `struct in6_addr`.

В настоящее время *address\_family* поддерживает значения [`AF_INET`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET) и [`AF_INET6`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET6). Если строка IP-адреса *ip\_string* недействительна, возбуждается [`socket.error`](https://python-all.ru/3.1/library/socket.html#socket.error). Имейте в виду, что точное определение допустимости зависит как от значения *address\_family*, так и от реализации `inet_pton()`.

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

#### `socket.inet_ntop(address_family, packed_ip)`

Convert a packed IP address (a bytes object of some number of characters) to its standard, family-specific string representation (for example, `'7.10.0.5'` or `'5aef:2b::8'`). [`inet_ntop()`](https://python-all.ru/3.1/library/socket.html#socket.inet_ntop) is useful when a library or network protocol returns an object of type `struct in_addr` (similar to [`inet_ntoa()`](https://python-all.ru/3.1/library/socket.html#socket.inet_ntoa)) or `struct in6_addr`.

В настоящее время *address\_family* поддерживает значения [`AF_INET`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET) и [`AF_INET6`](https://python-all.ru/3.1/library/socket.html#socket.AF_INET6). Если длина строки *packed\_ip* не соответствует указанному семейству адресов, возбуждается [`ValueError`](https://python-all.ru/3.1/library/exceptions.html#ValueError). [`socket.error`](https://python-all.ru/3.1/library/socket.html#socket.error) возбуждается при ошибках вызова [`inet_ntop()`](https://python-all.ru/3.1/library/socket.html#socket.inet_ntop).

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

#### `socket.getdefaulttimeout()`

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

`None`

означает, что у новых объектов сокета нет таймаута. При первом импорте модуля socket значение по умолчанию –

`None`

.

#### `socket.setdefaulttimeout(timeout)`

Устанавливает таймаут по умолчанию в секундах с плавающей запятой для новых объектов сокета. При первом импорте модуля socket значение по умолчанию –

`None`

. Информацию о возможных значениях и их смысле см. в

[`settimeout()`](https://python-all.ru/3.1/library/socket.html#socket.socket.settimeout)

.

#### `socket.SocketType`

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

`type(socket(...))`

.

## 17.2.3. Объекты сокетов

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

#### `socket.accept()`

Принимает соединение. Сокет должен быть привязан к адресу и прослушивать соединения. Возвращаемое значение – пара

`(conn, address)`

, где

*conn*

– это

*новый*

объект сокета, который можно использовать для отправки и получения данных по соединению, а

*address*

– это адрес, привязанный к сокету на другом конце соединения.

#### `socket.bind(address)`

Привязывает сокет к

*address*

. Сокет не должен быть уже привязан. (Формат

*address*

зависит от семейства адресов – см. выше.)

#### `socket.close()`

Закрывает сокет. Все последующие операции с объектом сокета будут завершаться ошибкой. Удаленная сторона не получит больше данных (после сброса находящихся в очереди данных). Сокеты автоматически закрываются при сборке мусора.

> **Примечание**
>
> [`close()`](https://python-all.ru/3.1/library/socket.html#socket.socket.close) освобождает ресурс, связанный с соединением, но не обязательно закрывает соединение немедленно. Если требуется вовремя закрыть соединение, вызовите [`shutdown()`](https://python-all.ru/3.1/library/socket.html#socket.socket.shutdown) перед [`close()`](https://python-all.ru/3.1/library/socket.html#socket.socket.close).

#### `socket.connect(address)`

Подключается к удалённому сокету по адресу

*address*

. (Формат

*address*

зависит от семейства адресов – см. выше.)

#### `socket.connect_ex(address)`

Как и

`connect(address)`

, но возвращает индикатор ошибки вместо вызова исключения для ошибок, возвращаемых вызовом

`connect()`

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

`0`

, если операция выполнена успешно, в противном случае – значению переменной

`errno`

. Это полезно, например, для поддержки асинхронных соединений.

#### `socket.fileno()`

Возвращает файловый дескриптор сокета (небольшое целое число). Это полезно с [`select.select()`](https://python-all.ru/3.1/library/select.html#select.select).

В Windows небольшое целое число, возвращаемое этим методом, нельзя использовать там, где может использоваться файловый дескриптор (например, в [`os.fdopen()`](https://python-all.ru/3.1/library/os.html#os.fdopen)). В Unix такого ограничения нет.

#### `socket.getpeername()`

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

#### `socket.getsockname()`

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

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

Возвращает значение указанной опции сокета (см. страницу man Unix

*getsockopt(2)*

). Необходимые символьные константы (

`SO_*`

и т.д.) определены в этом модуле. Если

*buflen*

отсутствует, предполагается целочисленная опция, и функция возвращает её целочисленное значение. Если

*buflen*

присутствует, он задает максимальную длину буфера для получения опции, и этот буфер возвращается в виде объекта bytes. Вызывающий код должен сам декодировать содержимое буфера (см. опциональный встроенный модуль

[`struct`](https://python-all.ru/3.1/library/struct.html#module-struct)

для способа декодирования структур C, закодированных как байтовые строки).

#### `socket.gettimeout()`

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

`None`

, если таймаут не установлен. Это значение отражает последний вызов

[`setblocking()`](https://python-all.ru/3.1/library/socket.html#socket.socket.setblocking)

или

[`settimeout()`](https://python-all.ru/3.1/library/socket.html#socket.socket.settimeout)

.

#### `socket.ioctl(control, option)`

| Платформа: | Windows |
| --- | --- |

Метод [`ioctl()`](https://python-all.ru/3.1/library/socket.html#socket.socket.ioctl) представляет собой ограниченный интерфейс к системному интерфейсу WSAIoctl. Для получения дополнительной информации обратитесь к [документации Win32](https://python-all.ru/3.1/library/socket.html).

On other platforms, the generic [`fcntl.fcntl()`](https://python-all.ru/3.1/library/fcntl.html#fcntl.fcntl) and [`fcntl.ioctl()`](https://python-all.ru/3.1/library/fcntl.html#fcntl.ioctl) functions may be used; they accept a socket object as their first argument.

#### `socket.listen(backlog)`

Ожидает подключения к сокету. Аргумент

*backlog*

задаёт максимальное количество ожидающих соединений в очереди и должен быть не менее 1; максимальное значение зависит от системы (обычно 5).

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

Возвращает [*файловый объект*](https://python-all.ru/3.1/glossary.html#term-file-object), связанный с сокетом. Точный возвращаемый тип зависит от аргументов, переданных в [`makefile()`](https://python-all.ru/3.1/library/socket.html#socket.socket.makefile). Эти аргументы интерпретируются так же, как и встроенной функцией [`open()`](https://python-all.ru/3.1/library/functions.html#open).

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

> **Примечание**
>
> В Windows файлоподобный объект, созданный [`makefile()`](https://python-all.ru/3.1/library/socket.html#socket.socket.makefile), нельзя использовать там, где требуется файловый объект с файловым дескриптором, например в аргументах потока [`subprocess.Popen()`](https://python-all.ru/3.1/library/subprocess.html#subprocess.Popen).

#### `socket.recv(bufsize[, flags])`

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

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

#### `socket.recvfrom(bufsize[, flags])`

Receive data from the socket. The return value is a pair

`(bytes, address)`

where

*bytes*

is a bytes object representing the data received and

*address*

is the address of the socket sending the data. See the Unix manual page

*recv(2)*

for the meaning of the optional argument

*flags*

; it defaults to zero. (The format of

*address*

depends on the address family – see above.)

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

Receive data from the socket, writing it into

*buffer*

instead of creating a new bytestring. The return value is a pair

`(nbytes, address)`

where

*nbytes*

is the number of bytes received and

*address*

is the address of the socket sending the data. See the Unix manual page

*recv(2)*

for the meaning of the optional argument

*flags*

; it defaults to zero. (The format of

*address*

depends on the address family – see above.)

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

Принимает до

*nbytes*

байт из сокета, сохраняя данные в буфер, а не создавая новую байтовую строку. Если

*nbytes*

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

*flags*

описан на странице руководства Unix

*recv(2)*

; по умолчанию он равен нулю.

#### `socket.send(bytes[, flags])`

Отправляет данные в сокет. Сокет должен быть подключён к удалённому сокету. Необязательный аргумент

*flags*

имеет тот же смысл, что и для

[`recv()`](https://python-all.ru/3.1/library/socket.html#socket.socket.recv)

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

#### `socket.sendall(bytes[, flags])`

Отправляет данные в сокет. Сокет должен быть подключён к удалённому сокету. Необязательный аргумент

*flags*

имеет то же значение, что и для

[`recv()`](https://python-all.ru/3.1/library/socket.html#socket.socket.recv)

выше. В отличие от

[`send()`](https://python-all.ru/3.1/library/socket.html#socket.socket.send)

, этот метод продолжает отправлять данные из

*bytes*

, пока не будут отправлены все данные или не возникнет ошибка. В случае успеха возвращается

`None`

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

#### `socket.sendto(bytes[, flags], address)`

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

*address*

. Необязательный аргумент

*flags*

имеет то же значение, что и для

[`recv()`](https://python-all.ru/3.1/library/socket.html#socket.socket.recv)

выше. Возвращает количество отправленных байт. (Формат

*address*

зависит от семейства адресов – см. выше.)

#### `socket.setblocking(flag)`

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

Этот метод является сокращением для некоторых вызовов [`settimeout()`](https://python-all.ru/3.1/library/socket.html#socket.socket.settimeout):

- `sock.setblocking(True)` эквивалентно `sock.settimeout(None)`
- `sock.setblocking(False)` эквивалентно `sock.settimeout(0.0)`

#### `socket.settimeout(value)`

Устанавливает тайм-аут для блокирующих операций с сокетом. Аргумент *value* может быть неотрицательным числом с плавающей запятой, выражающим секунды, или `None`. Если задано ненулевое значение, последующие операции с сокетом будут вызывать исключение [`timeout`](https://python-all.ru/3.1/library/socket.html#socket.timeout), если период тайм-аута *value* истек до завершения операции. Если задан ноль, сокет переводится в неблокирующий режим. Если задано `None`, сокет переводится в блокирующий режим.

Для получения дополнительной информации обратитесь к [*заметкам о тайм-аутах сокетов*](https://python-all.ru/3.1/library/socket.html#socket-timeouts).

#### `socket.setsockopt(level, optname, value)`

Устанавливает значение указанного параметра сокета (см. страницу руководства Unix *setsockopt(2)*). Необходимые символические константы определены в модуле `socket` (`SO_*` и т.д.). Значением может быть целое число или объект bytes, представляющий буфер. В последнем случае вызывающая сторона должна обеспечить, чтобы байтовая строка содержала правильные биты (см. дополнительный встроенный модуль [`struct`](https://python-all.ru/3.1/library/struct.html#module-struct) для способа кодирования структур C в виде байтовых строк).

#### `socket.shutdown(how)`

Завершает одну или обе половины соединения. Если

*how*

равно

`SHUT_RD`

, дальнейший приём данных запрещён. Если

*how*

равно

`SHUT_WR`

, дальнейшая отправка данных запрещена. Если

*how*

равно

`SHUT_RDWR`

, дальнейшие отправка и приём данных запрещены. В зависимости от платформы завершение одной половины соединения может также закрыть противоположную половину (например, на Mac OS X

`shutdown(SHUT_WR)`

не позволяет выполнять чтение на другом конце соединения).

Обратите внимание, что методов `read()` или `write()` не существует; вместо них используйте [`recv()`](https://python-all.ru/3.1/library/socket.html#socket.socket.recv) и [`send()`](https://python-all.ru/3.1/library/socket.html#socket.socket.send) без аргумента *flags*.

Объекты сокетов также имеют следующие (только для чтения) атрибуты, которые соответствуют значениям, переданным конструктору [`socket`](https://python-all.ru/3.1/library/socket.html#socket.socket).

#### `socket.family`

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

#### `socket.type`

Тип сокета.

#### `socket.proto`

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

## 17.2.4. Замечания о тайм-аутах сокетов

Объект сокета может находиться в одном из трёх режимов: блокирующем, неблокирующем или с тайм-аутом. По умолчанию сокеты всегда создаются в блокирующем режиме, но это можно изменить, вызвав [`setdefaulttimeout()`](https://python-all.ru/3.1/library/socket.html#socket.setdefaulttimeout).

- В *блокирующем режиме* операции блокируются до завершения или пока система не вернет ошибку (например, истекло время соединения).
- В *неблокирующем режиме* операции завершаются ошибкой (с ошибкой, которая, к сожалению, зависит от системы), если их нельзя выполнить немедленно: функции из модуля [`select`](https://python-all.ru/3.1/library/select.html#module-select) можно использовать, чтобы узнать, когда и доступен ли сокет для чтения или записи.
- В *режиме с тайм-аутом* операции завершаются ошибкой, если их нельзя выполнить в течение тайм-аута, указанного для сокета (они вызывают исключение [`timeout`](https://python-all.ru/3.1/library/socket.html#socket.timeout)), или если система возвращает ошибку.

> **Примечание**
>
> На уровне операционной системы сокеты в *режиме с тайм-аутом* внутренне устанавливаются в неблокирующий режим. Кроме того, блокирующий режим и режим тайм-аута разделяются между файловыми дескрипторами и объектами сокетов, которые относятся к одной и той же сетевой конечной точке. Эта деталь реализации может иметь заметные последствия, если, например, вы решите использовать [`fileno()`](https://python-all.ru/3.1/library/socket.html#socket.socket.fileno) сокета.

### 17.2.4.1. Тайм-ауты и метод `connect`

Операция [`connect()`](https://python-all.ru/3.1/library/socket.html#socket.socket.connect) также подчиняется настройке тайм-аута, и в целом рекомендуется вызывать [`settimeout()`](https://python-all.ru/3.1/library/socket.html#socket.socket.settimeout) перед вызовом [`connect()`](https://python-all.ru/3.1/library/socket.html#socket.socket.connect) или передавать параметр тайм-аута в [`create_connection()`](https://python-all.ru/3.1/library/socket.html#socket.create_connection). Однако сетевой стек системы также может вернуть собственную ошибку тайм-аута соединения независимо от любой настройки тайм-аута сокета Python.

## 17.2.5. Пример

Вот четыре минимальных примера программ, использующих протокол TCP/IP: сервер, который отправляет обратно все полученные данные (обслуживая только одного клиента), и клиент, использующий его. Обратите внимание, что сервер должен выполнить последовательность [`socket()`](https://python-all.ru/3.1/library/socket.html#socket.socket), [`bind()`](https://python-all.ru/3.1/library/socket.html#socket.socket.bind), [`listen()`](https://python-all.ru/3.1/library/socket.html#socket.socket.listen), [`accept()`](https://python-all.ru/3.1/library/socket.html#socket.socket.accept) (возможно, повторяя [`accept()`](https://python-all.ru/3.1/library/socket.html#socket.socket.accept) для обслуживания более чем одного клиента), в то время как клиенту нужна только последовательность [`socket()`](https://python-all.ru/3.1/library/socket.html#socket.socket), [`connect()`](https://python-all.ru/3.1/library/socket.html#socket.socket.connect). Также обратите внимание, что сервер не вызывает [`send()`](https://python-all.ru/3.1/library/socket.html#socket.socket.send)/[`recv()`](https://python-all.ru/3.1/library/socket.html#socket.socket.recv) на сокете, который прослушивает, а на новом сокете, возвращённом [`accept()`](https://python-all.ru/3.1/library/socket.html#socket.socket.accept).

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

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

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

```python
# Программа эхо-клиента
import socket

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

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

```python
# Программа эхо-сервера
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 socket.error as msg:
        s = None
        continue
    try:
        s.bind(sa)
        s.listen(1)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print('could not open socket')
    sys.exit(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)
conn.close()
```

```python
# Программа эхо-клиента
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 socket.error as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print('could not open socket')
    sys.exit(1)
s.send(b'Hello, world')
data = s.recv(1024)
s.close()
print('Received', repr(data))
```

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

```python
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)
```

> **См. также**
>
> Для ознакомления с программированием сокетов (на 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**](https://python-all.ru/3.1/library/socket.html) под названием Basic Socket Interface Extensions for IPv6.
