Содержание страницы
socket – низкоуровневый сетевой интерфейс¶socket – Low-level networking interface
Этот модуль предоставляет доступ к интерфейсу BSD socket. Он доступен во всех современных Unix-системах, Windows, MacOS, OS/2 и, вероятно, на других платформах.
Примечание
Некоторые аспекты поведения могут зависеть от платформы, поскольку вызовы выполняются через API сокетов операционной системы.
Для введения в программирование сокетов (на C) см. следующие статьи: «An Introductory 4.3BSD Interprocess Communication Tutorial» (Стюарт Сечрест) и «An Advanced 4.3BSD Interprocess Communication Tutorial» (Сэмюэл Дж. Леффлер и др.), обе в UNIX Programmer’s Manual, Supplementary Documents 1 (разделы PS1:7 и PS1:8). Справочные материалы, специфичные для платформы, по различным системным вызовам сокетов также являются ценным источником информации о деталях семантики сокетов. Для Unix обратитесь к man-страницам; для Windows – к спецификации WinSock (или Winsock 2). Для API, поддерживающих IPv6, читателям рекомендуется обратиться к RFC 3493 под названием «Basic Socket Interface Extensions for IPv6».
Интерфейс Python представляет собой прямую трансляцию системных вызовов и библиотечного интерфейса сокетов Unix в объектно-ориентированном стиле Python: функция socket() возвращает объект сокета, методы которого реализуют различные системные вызовы сокетов. Типы параметров находятся на более высоком уровне, чем в интерфейсе C: как и при операциях read() и write() с файлами Python, выделение буфера при приёме происходит автоматически, а длина буфера при отправке подразумевается неявно.
Адреса сокетов представляются следующим образом: для семейства адресов AF_UNIX используется одна строка. Для семейства адресов AF_INET используется пара (host, port), где host – строка, представляющая либо имя хоста в нотации интернет-доменов, например 'daring.cwi.nl', либо IPv4-адрес, например '100.50.200.5', а port – целочисленный номер порта. Для семейства адресов AF_INET6 используется четверка (host, port, flowinfo, scopeid), где flowinfo и scopeid представляют члены sin6_flowinfo и sin6_scope_id в структуре struct sockaddr_in6 в C. Для методов модуля socket flowinfo и scopeid могут быть опущены только для обратной совместимости. Однако обратите внимание, что опускание scopeid может вызвать проблемы при работе с scoped IPv6-адресами. Другие семейства адресов в настоящее время не поддерживаются. Формат адреса, требуемый конкретным объектом сокета, автоматически выбирается на основе семейства адресов, указанного при создании объекта сокета.
Для IPv4-адресов вместо адреса хоста принимаются две специальные формы: пустая строка представляет INADDR_ANY, а строка '<broadcast>' представляет INADDR_BROADCAST. Это поведение недоступно для IPv6 из соображений обратной совместимости, поэтому, если вы планируете поддерживать IPv6 в своих программах на Python, лучше избегать этих форм.
Если в части узел адреса сокета IPv4/v6 указано имя узла, программа может демонстрировать недетерминированное поведение, так как Python использует первый адрес, возвращённый при разрешении DNS. Адрес сокета будет разрешаться по-разному в фактический IPv4/v6-адрес в зависимости от результатов разрешения DNS и/или конфигурации узла. Для детерминированного поведения используйте числовой адрес в части узел.
Сокеты 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.
Все ошибки вызывают исключения. Могут возникать обычные исключения для недопустимых типов аргументов и нехватки памяти; ошибки, связанные с семантикой сокетов или адресов, вызывают исключение socket.error.
Неблокирующий режим поддерживается с помощью setblocking(). Обобщение этого подхода на основе тайм-аутов реализовано через settimeout().
Модуль socket экспортирует следующие константы и функции:
- exception socket.error¶
Это исключение возникает при ошибках, связанных с сокетами. Сопутствующее значение – либо строка с описанием ошибки, либо пара (errno, string), представляющая ошибку, возвращенную системным вызовом, аналогично значению, сопутствующему os.error. См. модуль errno, который содержит имена для кодов ошибок, определенных базовой операционной системой.
- exception socket.herror¶
Это исключение возникает при ошибках, связанных с адресами, т.е. для функций, использующих h_errno в C API, включая gethostbyname_ex() и gethostbyaddr().
Сопутствующее значение – это пара (h_errno, string), представляющая ошибку, возвращённую библиотечным вызовом. string представляет описание h_errno, возвращаемое функцией hstrerror из C.
- exception socket.gaierror¶
- Это исключение возникает при ошибках, связанных с адресами, для getaddrinfo() и getnameinfo(). Сопутствующее значение – это пара (error, string), представляющая ошибку, возвращённую библиотечным вызовом. string представляет описание error, возвращаемое функцией gai_strerror из C. Значение error будет соответствовать одной из констант EAI_*, определённых в этом модуле.
- exception socket.timeout¶
- Это исключение возникает, когда происходит тайм-аут на сокете, для которого тайм-ауты были включены предыдущим вызовом settimeout(). Сопутствующее значение – это строка, которая в настоящее время всегда равна «timed out».
- 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.)
- 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().
- socket.getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]])¶
Resolves the host/port argument, into a sequence of 5-tuples that contain all the necessary arguments for creating the corresponding socket. host is a domain name, a string representation of an IPv4/v6 address or None. port is a string service name such as 'http', a numeric port number or None. The rest of the arguments are optional and must be numeric if specified. By passing None as the value of host and port, , you can pass NULL to the C API.
Функция getaddrinfo() возвращает список кортежей из 5 элементов со следующей структурой:
(семейство, тип сокета, протокол, каноническое имя, адрес сокета)
family, socktype, proto – целые числа и предназначены для передачи в функцию socket(). canonname – строка, представляющая каноническое имя хоста. Она может быть числовым IPv4/v6 адресом, если для числового хоста указан AI_CANONNAME. sockaddr – кортеж, описывающий адрес сокета, как описано выше. См. исходный код socket и других библиотечных модулей для получения типичного примера использования функции.
- socket.getfqdn([name])¶
- Возвращает полное доменное имя для name. Если name опущен или пуст, он интерпретируется как локальный хост. Чтобы найти полное имя, проверяется имя хоста, возвращённое gethostbyaddr(), а затем, при наличии, псевдонимы хоста. Выбирается первое имя, содержащее точку. Если полное доменное имя недоступно, возвращается имя хоста, полученное через gethostname().
- socket.gethostbyname(hostname)¶
- Преобразует имя хоста в формат IPv4-адреса. IPv4-адрес возвращается в виде строки, например '100.50.200.5'. Если само имя хоста является IPv4-адресом, оно возвращается без изменений. См. gethostbyname_ex() для более полного интерфейса. gethostbyname() не поддерживает разрешение имён IPv6, поэтому для поддержки dual stack IPv4/v6 следует использовать getaddrinfo().
- socket.gethostbyname_ex(hostname)¶
- Преобразует имя хоста в формат IPv4-адреса, расширенный интерфейс. Возвращает тройку (hostname, aliaslist, ipaddrlist), где hostname – основное имя хоста, отвечающего на заданный ip_address, aliaslist – (возможно, пустой) список альтернативных имён хоста для того же адреса, а ipaddrlist – список IPv4-адресов того же интерфейса на том же хосте (часто, но не всегда, один адрес). gethostbyname_ex() не поддерживает разрешение имён IPv6, поэтому для поддержки dual stack IPv4/v6 следует использовать getaddrinfo().
- socket.gethostname()¶
Возвращает строку, содержащую имя хоста машины, на которой в данный момент выполняется интерпретатор Python.
Если нужно узнать IP-адрес текущей машины, можно использовать gethostbyname(gethostname()). Эта операция предполагает, что существует корректное отображение адреса на хост, и это предположение выполняется не всегда.
Примечание: gethostname() не всегда возвращает полное доменное имя; используйте getfqdn() (см. выше).
- socket.gethostbyaddr(ip_address)¶
- Возвращает тройку (hostname, aliaslist, ipaddrlist), где hostname – основное имя хоста, отвечающего на заданный ip_address, aliaslist – (возможно, пустой) список альтернативных имён хоста для того же адреса, а ipaddrlist – список IPv4/v6-адресов того же интерфейса на том же хосте (скорее всего, содержащий только один адрес). Чтобы найти полное доменное имя, используйте функцию getfqdn(). gethostbyaddr() поддерживает как IPv4, так и IPv6.
- socket.getnameinfo(sockaddr, flags)¶
- Преобразует адрес сокета sockaddr в кортеж из двух элементов (host, port). В зависимости от настроек flags результат может содержать полное доменное имя или числовое представление адреса в host. Аналогично, port может содержать строковое имя порта или числовой номер порта.
- socket.getprotobyname(protocolname)¶
- Преобразует имя интернет-протокола (например, 'icmp') в константу, пригодную для передачи в качестве (необязательного) третьего аргумента функции socket(). Обычно это требуется только для сокетов, открытых в «сыром» режиме (SOCK_RAW); для обычных режимов сокета правильный протокол выбирается автоматически, если протокол опущен или равен нулю.
- socket.getservbyname(servicename[, protocolname])¶
- Преобразует имя интернет-службы и имя протокола в номер порта для этой службы. Необязательное имя протокола, если указано, должно быть 'tcp' или 'udp', в противном случае подойдёт любой протокол.
- socket.getservbyport(port[, protocolname])¶
- Преобразует номер порта и имя протокола в имя службы для этой службы. Необязательное имя протокола, если указано, должно быть 'tcp' или 'udp', иначе подойдет любой протокол.
- socket.socket([family[, type[, proto]]])¶
- Создаёт новый сокет с заданным семейством адресов, типом сокета и номером протокола. Семейство адресов должно быть AF_INET (по умолчанию), AF_INET6 или AF_UNIX. Тип сокета должен быть SOCK_STREAM (по умолчанию), SOCK_DGRAM или, возможно, одна из констант SOCK_. Номер протокола обычно равен нулю и в этом случае может быть опущен.
- socket.socketpair([family[, type[, proto]]])¶
- Создаёт пару соединённых объектов сокетов, используя указанное семейство адресов, тип сокета и номер протокола. Семейство адресов, тип сокета и номер протокола такие же, как для функции socket() выше. Семейство по умолчанию – AF_UNIX, если оно определено на платформе; в противном случае по умолчанию используется AF_INET. Доступность: Unix.
- socket.fromfd(fd, family, type[, proto])¶
- Дублирует файловый дескриптор fd (целое число, возвращаемое методом fileno() файлового объекта) и создаёт из результата объект сокета. Семейство адресов, тип сокета и номер протокола – как у функции 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-битного упакованного двоичного представления, возвращаемого этой функцией.
Если переданная этой функции строка IPv4-адреса недопустима, будет возбуждено socket.error. Обратите внимание, что точное определение допустимости зависит от нижележащей реализации C функции inet_aton.
inet_aton() не поддерживает IPv6, и для поддержки двойного стека IPv4/v6 вместо него следует использовать getnameinfo().
- socket.inet_ntoa(packed_ip)¶
Преобразует 32-битный упакованный IPv4-адрес (объект bytes длиной четыре символа) в его стандартное строковое представление с точками (например, '123.45.67.89'). Это полезно при взаимодействии с программой, использующей стандартную библиотеку C и требующей объекты типа struct in_addr, который является типом C для 32-битных упакованных двоичных данных, принимаемых этой функцией в качестве аргумента.
Если длина переданной этой функции последовательности байтов не равна ровно 4 байтам, будет возбуждено socket.error. inet_ntoa() не поддерживает IPv6, и для поддержки двойного стека IPv4/v6 вместо него следует использовать getnameinfo().
- 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 недопустима, будет возбуждено 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() is useful when a library or network protocol returns an object of type struct in_addr (similar to inet_ntoa()) or struct in6_addr.
В настоящее время address_family поддерживает значения AF_INET и AF_INET6. Если длина строки packed_ip не соответствует указанному семейству адресов, возбуждается ValueError. socket.error возбуждается при ошибках вызова inet_ntop().
Доступность: Unix (возможно, не на всех платформах).
- socket.getdefaulttimeout()¶
- Возвращает таймаут по умолчанию в секундах с плавающей запятой для новых объектов сокета. Значение None означает, что у новых объектов сокета нет таймаута. При первом импорте модуля socket значение по умолчанию – None.
- socket.setdefaulttimeout(timeout)¶
- Устанавливает тайм-аут по умолчанию для новых сокетных объектов в секундах с плавающей запятой. Значение None означает, что новые сокетные объекты не имеют тайм-аута. При первом импорте модуля socket значением по умолчанию является None.
- socket.SocketType¶
- Это объект типа Python, представляющий тип объекта сокета. Он эквивалентен type(socket(...)).
См. также
- Модуль socketserver
- Классы, упрощающие написание сетевых серверов.
Объекты сокетов¶Socket Objects
Объекты сокетов имеют следующие методы. За исключением makefile(), они соответствуют системным вызовам Unix, применимым к сокетам.
- socket.accept()¶
- Принимает соединение. Сокет должен быть привязан к адресу и прослушивать соединения. Возвращаемое значение – пара (conn, address), где conn – это новый объект сокета, который можно использовать для отправки и получения данных по соединению, а address – это адрес, привязанный к сокету на другом конце соединения.
- socket.bind(address)¶
- Привязывает сокет к address. Сокет не должен быть уже привязан. (Формат address зависит от семейства адресов – см. выше.)
- socket.close()¶
- Закрывает сокет. Все последующие операции с объектом сокета будут завершаться ошибкой. Удаленная сторона не получит больше данных (после сброса находящихся в очереди данных). Сокеты автоматически закрываются при сборке мусора.
- socket.connect(address)¶
- Подключается к удалённому сокету по адресу address. (Формат address зависит от семейства адресов – см. выше.)
- socket.connect_ex(address)¶
- Похож на connect(address), но возвращает индикатор ошибки вместо возбуждения исключения для ошибок, возвращаемых вызовом C-уровня connect (другие проблемы, например, «хост не найден», по-прежнему могут возбуждать исключения). Индикатор ошибки равен 0, если операция выполнена успешно, в противном случае – значению переменной errno. Это полезно, например, для поддержки асинхронных соединений.
- socket.fileno()¶
Возвращает файловый дескриптор сокета (небольшое целое число). Это полезно с select.select().
В Windows небольшое целое число, возвращаемое этим методом, нельзя использовать там, где может использоваться файловый дескриптор (например, в 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 для способа декодирования структур C, закодированных как байтовые строки).
- socket.ioctl(control, option)¶
Платформа: Windows Метод ioctl() представляет собой ограниченный интерфейс к системному интерфейсу WSAIoctl. За дополнительной информацией обратитесь к документации MSDN.
- socket.listen(backlog)¶
- Ожидает подключения к сокету. Аргумент backlog задаёт максимальное количество ожидающих соединений в очереди и должен быть не менее 1; максимальное значение зависит от системы (обычно 5).
- socket.makefile([mode[, bufsize]])¶
Возвращает файловый объект, связанный с сокетом. (Файловые объекты описаны в разделе Файловые объекты.) Файловый объект ссылается на dupлированную версию файлового дескриптора сокета, поэтому файловый объект и объект сокета могут быть закрыты или собраны сборщиком мусора независимо. Сокет должен находиться в блокирующем режиме (он не может иметь тайм-аут). Необязательные аргументы mode и bufsize интерпретируются так же, как и встроенной функцией file().
- 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() выше. Возвращает количество отправленных байт. Приложения должны проверять, что все данные были отправлены; если передана только часть данных, приложению необходимо повторить попытку отправки оставшихся данных.
- socket.sendall(bytes[, flags])¶
- Отправляет данные в сокет. Сокет должен быть подключён к удалённому сокету. Необязательный аргумент flags имеет то же значение, что и для recv() выше. В отличие от send(), этот метод продолжает отправлять данные из bytes, пока не будут отправлены все данные или не возникнет ошибка. В случае успеха возвращается None. При ошибке вызывается исключение, и невозможно определить, сколько данных (если вообще было) было успешно отправлено.
- socket.sendto(bytes[, flags], address)¶
- Отправляет данные в сокет. Сокет не должен быть подключён к удалённому сокету, так как целевой сокет задаётся аргументом address. Необязательный аргумент flags имеет то же значение, что и для recv() выше. Возвращает количество отправленных байт. (Формат address зависит от семейства адресов – см. выше.)
- socket.setblocking(flag)¶
- Устанавливает блокирующий или неблокирующий режим сокета: если flag равен 0, сокет переводится в неблокирующий режим, иначе – в блокирующий. Изначально все сокеты работают в блокирующем режиме. В неблокирующем режиме, если вызов recv() не находит данных или вызов send() не может немедленно отправить данные, возбуждается исключение error; в блокирующем режиме вызовы блокируются до завершения. s.setblocking(0) эквивалентно s.settimeout(0); s.setblocking(1) эквивалентно s.settimeout(None).
- socket.settimeout(value)¶
- Устанавливает тайм-аут для блокирующих операций с сокетом. Аргумент value может быть неотрицательным числом с плавающей запятой, выражающим секунды, или None. Если передано число с плавающей запятой, последующие операции с сокетом будут возбуждать исключение timeout, если период тайм-аута value истёк до завершения операции. Установка тайм-аута None отключает тайм-ауты для операций с сокетом. s.settimeout(0.0) эквивалентно s.setblocking(0); s.settimeout(None) эквивалентно s.setblocking(1).
- socket.gettimeout()¶
- Возвращает тайм-аут в секундах с плавающей запятой, связанный с операциями сокета, или None, если тайм-аут не установлен. Это отражает последний вызов setblocking() или settimeout().
Несколько замечаний о блокировке и тайм-аутах сокетов: объект сокета может находиться в одном из трёх режимов: блокирующий, неблокирующий или тайм-аут. Сокеты всегда создаются в блокирующем режиме. В блокирующем режиме операции блокируются до завершения. В неблокирующем режиме операции завершаются ошибкой (с системно-зависимой ошибкой), если их невозможно выполнить немедленно. В режиме тайм-аута операции завершаются ошибкой, если их невозможно выполнить в течение заданного для сокета тайм-аута. Метод setblocking() является просто сокращённой записью для некоторых вызовов settimeout().
Режим тайм-аута внутренне переводит сокет в неблокирующий режим. Режимы блокировки и тайм-аута являются общими для файловых дескрипторов и объектов сокетов, указывающих на одну и ту же сетевую конечную точку. Следствием этого является то, что файловые объекты, возвращаемые методом makefile(), должны использоваться только при блокирующем режиме сокета; в режиме тайм-аута или неблокирующем режиме файловые операции, которые не могут быть выполнены немедленно, завершатся ошибкой.
Обратите внимание, что на операцию connect() распространяется настройка тайм-аута, и в целом рекомендуется вызывать settimeout() перед вызовом connect().
- socket.setsockopt(level, optname, value)¶
Устанавливает значение указанного параметра сокета (см. страницу руководства Unix setsockopt(2)). Необходимые символические константы определены в модуле socket (SO_* и т.д.). Значением может быть целое число или объект bytes, представляющий буфер. В последнем случае вызывающая сторона должна обеспечить, чтобы байтовая строка содержала правильные биты (см. дополнительный встроенный модуль struct для способа кодирования структур C в виде байтовых строк).
- socket.shutdown(how)¶
- Завершает одну или обе половины соединения. Если how равно SHUT_RD, дальнейший приём запрещён. Если how равно SHUT_WR, дальнейшая отправка запрещена. Если how равно SHUT_RDWR, дальнейшие отправка и приём запрещены.
Обратите внимание, что методы read() или write() отсутствуют; вместо них используйте recv() и send() без аргумента flags.
Объекты сокетов также имеют следующие (только для чтения) атрибуты, которые соответствуют значениям, переданным конструктору socket.
- socket.family¶
- Семейство сокета.
- socket.type¶
- Тип сокета.
- socket.proto¶
- Протокол сокета.
Пример¶Example
Вот четыре минимальных примера программ, использующих протокол TCP/IP: сервер, который отправляет обратно все полученные данные (обслуживая только одного клиента), и клиент, использующий его. Обратите внимание, что сервер должен выполнить последовательность socket(), bind(), listen(), accept() (возможно, повторяя accept() для обслуживания нескольких клиентов), в то время как клиенту нужна только последовательность socket(), connect(). Также обратите внимание, что сервер выполняет send()/recv() не на том сокете, на котором он слушает, а на новом сокете, возвращённом accept().
Первые два примера поддерживают только IPv4.
# Программа эхо-сервера
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()
# Программа эхо-клиента
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-трафик. Клиентская сторона попытается подключиться ко всем адресам, полученным в результате разрешения имен, и отправляет трафик на первый успешно подключенный.
# Программа эхо-сервера
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()
# Программа эхо-клиента
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. Для выполнения примера требуются права администратора для изменения интерфейса:
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)