Главная страница

справочник по Python. мм isbn 9785932861578 9 785932 861578


Скачать 4.21 Mb.
Названиемм isbn 9785932861578 9 785932 861578
Анкорсправочник по Python
Дата08.05.2022
Размер4.21 Mb.
Формат файлаpdf
Имя файлаBizli_Python-Podrobnyy-spravochnik.440222.pdf
ТипСправочник
#518195
страница54 из 82
1   ...   50   51   52   53   54   55   56   57   ...   82
599
Имя параметра
Значение
Описание
SO_SNDTIMEO
timeval
М
аксимальное время ожидания в секундах при передаче данных. Описание значение типа timeval приводится в описании параметра
SO_RCVTIMEO
SO_TYPE
int
Тип сокета.
SO_USELOOPBACK
0, 1
Разрешает или запрещает маршрутизирующе- му сокету получать копии отправляемых им пакетов.
Следующие параметры доступны для уровня IPPROTO_IP:
Имя параметра
Значение
Описание
IP_ADD_MEMBERSHIP
ip_mreg
Включение в группу многоадресной передачи
(доступен только для записи). Значение типа ip_mreg представляет собой упакованную дво- ичную строку, содержащую два 32-битных
IP-адреса (multiaddr, localaddr), где число
multiaddr
определяет групповой адрес, а число
localaddr

IP-адрес используемого локального интерфейса.
IP_DROP_MEMBERSHIP
ip_mreg
Выход из группы многоадресной передачи (до- ступен только для записи). Описание значения типа ip_mreg приводится выше.
IP_HDRINCL
int
Включается IP-заголовок.
IP_MAX_MEMBERSHIPS
int
Максимальное количество многоадресных групп.
IP_MULTICAST_IF
in_addr
Определяет исходящий интерфейс. Значение типа in_addr представляет собой упакованную двоичную строку, содержащую два 32-битных
IP-адреса.
IP_MULTICAST_LOOP
0, 1
Разрешает или запрещает отправку копий па- кетов на тот узел, откуда он был отправлен.
IP_MULTICAST_TTL
uint8
Определяет «время жизни» (time-to-live) ис- ходящих многоадресных пакетов. Значение типа int8 представляет собой упакованную двоичную строку, содержащую 8-битное целое число без знака.
IP_OPTIONS
ipopts
Параметры IP-заголовка. Значение типа ipopts представляет собой упакованную двоичную строку длиной не более 44 байтов. Содержимое этой строки описывается в RFC 791.
IP_RECVDSTADDR
0, 1
Разрешает или запрещает принимать IP-адрес получателя в виде дейтаграммы.

600
Глава 21. Работа с сетью и сокеты
Имя параметра
Значение
Описание
IP_RECVOPTS
0, 1
Разрешает или запрещает принимать все IP- параметры в виде дейтаграммы.
IP_RECVRETOPTS
0, 1
Разрешает или запрещает принимать IP- параметры с ответом.
IP_RETOPTS
0, 1
То же, что и IP_RECVOPTS, но параметры остают- ся необработанными, с пустой отметкой време- ни и с пустой маршрутной записью.
IP_TOS
int
Тип обслуживания.
IP_TTL
int
Значение поля TTL пакета («время жизни»).
Следующие параметры доступны для уровня IPPROTO_IPV6:
Имя параметра
Значение
Описание
IPV6_CHECKSUM
0, 1
Разрешает или запрещает вычислять кон- трольную сумму.
IPV6_DONTFRAG
0, 1
Разрешает или запрещает фрагментировать пакеты, размер которых превышает размер
MTU.
IPV6_DSTOPTS
ip6_dest
Параметры получателя. Значение типа ip6_
dest
представляет собой упакованную двоич- ную строку вида (next, len, options), где поле
next
содержит 8-битное целое число, опреде- ляющее тип параметра следующего заголовка;
len
– 8-битное целое число, определяющее дли- ну заголовка в блоках по 8 байтов, не включая первые 8 байтов; и options – параметры коди- рования.
IPV6_HOPLIMIT
int
Предельное количество транзитных узлов.
IPV6_HOPOPTS
ip6_hbh
Параметры транзитных узлов. Значение типа
ip6_hbh
интерпретируется так же, как и значе- ние типа ip6_dest.
IPV6_JOIN_GROUP
ip6_mreg
Включение в группу многоадресной передачи.
Значение типа ip6_mreg представляет собой упакованную двоичную строку вида (multiaddr,
index)
, где multiaddr определяет 128-битный групповой адрес IPv6, а число index – 32-бит- ный целочисленный индекс используемого локального интерфейса.
IPV6_LEAVE_GROUP
ip6_mreg
Выход из группы многоадресной передачи.
IPV6_MULTICAST_HOPS
int
Предельное количество транзитных узлов для многоадресных пакетов.
(продолжение)

Модуль socket
601
Имя параметра
Значение
Описание
IPV6_MULTICAST_IF
int
Индекс интерфейса для исходящих много- адресных пакетов.
IPV6_MULTICAST_LOOP
0, 1
Разрешает или запрещает отправку копий па- кетов обратно локальному приложению.
IPV6_NEXTHOP
sockaddr_
in6
Определяет адрес следующего транзитного узла для исходящих пакетов. Значение типа
sockaddr_in6
представляет собой упакованную двоичную строку, содержащую структуру sockaddr_in6
на языке C, определение которой обычно находится в файле .
IPV6_PKTINFO
ip6_pktinfo
Структура с информацией о пакете. Значение типа ip6_pktinfo представляет собой упакован- ную двоичную строку вида (addr, index), где поле addr представляет 128-битный адрес IPv6, а поле index – 32-битный целочисленный ин- декс интерфейса.
IPV6_RECVDSTOPTS
0, 1
Разрешает или запрещает прием параметров получателя.
IPV6_RECVHOPLIMIT
0, 1
Разрешает или запрещает прием максималь- ного количества транзитных узлов.
IPV6_RECVHOPOPTS
0, 1
Разрешает или запрещает прием параметров транзитных узлов.
IPV6_RECVPKTINFO
0, 1
Разрешает или запрещает прием информации о пакете.
IPV6_RECVRTHDR
0, 1
Разрешает или запрещает прием заголовка маршрутизации.
IPV6_RECVTCLASS
0, 1
Разрешает или запрещает принимать класс трафика.
IPV6_RTHDR
ip6_rthdr
Заголовок маршрутизации. Значение типа ip6_
rthdr
представляет собой упакованную дво- ичную строку вида (next, len, type, segleft,
data)
, где поля next, len, type и segleft являются
8-битными целыми числами без знака, а поле
data
содержит информацию о маршрутизации.
Подробности смотрите в RFC 2460.
IPV6_RTHDRDSTOPTS
ip6_dest
Заголовок с параметрами получателя, следую- щий перед заголовком с параметрами маршру- тизации.
IPV6_RECVPATHMTU
0, 1
Разрешает или запрещает получение вспомога- тельных данных IPV6_PATHMTU.
IPV6_TCLASS
int
Класс трафика.
IPV6_UNICAST_HOPS
int
Предельное количество транзитных узлов для одноадресных пакетов.

602
Глава 21. Работа с сетью и сокеты
Имя параметра
Значение
Описание
IPV6_USE_MIN_MTU
-1, 0, 1
Разрешает или запрещает поиск маршрута с подходящим значением MTU. 1 – запрещает для всех получателей. -1 – запрещает только при многоадресной рассылке.
IPV6_V6ONLY
0, 1
Разрешает или запрещает устанавливать со- единения только с узлами, поддерживающими
IPv6.
Следующие параметры доступны для уровня SOL_TCP:
Имя параметра
Значение
Описание
TCP_CORK
0, 1
Значение 1 запрещает передавать неполные кадры.
TCP_DEFER_ACCEPT
0, 1
Активировать прослушивание сети только по прибытии данных в сокет.
TCP_INFO
tcp_info
Возвращает структуру с информацией о соке- те. Содержимое структуры tcp_info зависит от реализации.
TCP_KEEPCNT
int
Максимальное количество попыток отправить служебное сообщение для поддержания соеди- нения в активном состоянии, прежде чем при- знать соединение разорванным.
TCP_KEEPIDLE
int
Время простоя соединения в секундах, прежде чем начнется передача служебных сообщений, используемых для поддержания соединения в активном состоянии, если установлен пара- метр TCP_KEEPALIVE.
TCP_KEEPINTVL
int
Интервал в секундах между передачами слу- жебных сообщений, используемых для поддер- жания соединения в активном состоянии.
TCP_LINGER2
int
Предельное время нахождения сокета в со- стоянии FIN_WAIT2.
TCP_MAXSEG
int
Максимальный размер сегмента для исходя- щих пакетов TCP.
TCP_NODELAY
0, 1
Значение 1 запрещает использование алгорит- ма Нагла.
TCP_QUICKACK
0, 1
При значении 1 пакеты ACK передаются не- медленно. Запрещает использование алгорит- ма задержки отправки пакетов ACK.
TCP_SYNCNT
int
Число повторных попыток передачи пакета
SYN до того, как будет принято решение о не- возможности установить соединение.
(продолжение)

Модуль socket
603
Имя параметра
Значение
Описание
TCP_WINDOW_CLAMP
int
Определяет верхнюю границу предлагаемого размера окна TCP.
s.gettimeout()
Возвращает текущее значение предельного времени ожидания в секундах, если установлено. Возвращает число с плавающей точкой или None, если предельное время ожидания не было установлено.
s.ioctl(control, option)
Предоставляет ограниченный доступ к интерфейсу WSAIoctl в системе
Windows. Для аргумента control поддерживается только значение SIO_
RCVALL
, которое применяется для перехвата всех IP-пакетов в сети. Для ра-
IP-пакетов в сети. Для ра-
-пакетов в сети. Для ра- ра- ра- боты требует привилегий администратора. В аргументе option допускается передавать следующие значения:
Параметр
Описание
RCVALL_OFF
Запрещает прием всех пакетов IPv4 и IPv6.
RCVALL_ON
Включает режим прослушивания (promiscuous) и по- promiscuous) и по-
) и по- зволяет сокету принимать все пакеты IPv4 и IPv6, курси-
Pv4 и IPv6, курси- v4 и IPv6, курси-
Pv6, курси- v6, курси- рующие в сети. Тип принимаемых пакетов определяется семейством адресов, установленных для сокета. Перехват пакетов других сетевых протоколов, таких как ARP, не выполняется.
RCVALL_IPLEVEL
Принимает все IP-пакеты, но отключает режим прослуши- вания. Будет захватывать все пакеты, направляемые на любой IP-адрес, присвоенный данному хосту.
s.listen(backlog)
Переводит сокет в режим ожидания входящих соединений. Аргумент
backlog
определяет максимальное количество запросов на соединение, ожидающих обработки, которые могут быть приняты, прежде чем новые запросы начнут отвергаться. Этот аргумент должен иметь значение не меньше 1, а значения 5 вполне достаточно для большинства применений.
s.makefile([mode [, bufsize]])
Создает объект файла, ассоциированного с сокетом. Аргументы mode и bufsize имеют тот же смысл, что и во встроенной функции open(). Объект файла использует дубликат файлового дескриптора сокета, созданного с по- мощью функции os.dup(), благодаря этому объект файла и объект сокета мо- гут закрываться или утилизироваться сборщиком мусора независимо друг от друга. Для сокета s не должно быть определено предельное время ожи- дания и он не должен быть настроен на работу в неблокирующем режиме.
s.recv(bufsize [, flags])
Принимает данные из сокета. Данные возвращаются в виде строки. Мак- симальный объем принимаемых данных определяется аргументом bufsize.

604
Глава 21. Работа с сетью и сокеты
В аргументе flags может передаваться дополнительная информация о со- общении, но обычно он не используется (в этом случае он по умолчанию принимает значение 0). Если используется, в нем, как правило, передается значение одной из следующих констант (фактические значения зависят от системы):
Константа
Описание
MSG_DONTROUTE
Не использовать таблицу маршрутизации (только для передачи).
MSG_DONTWAIT
Использовать неблокирующий режим.
MSG_EOR
Признак последнего сообщения в записи. Обычно используется только при передаче данных в сокеты типа SOCK_SEQPACKET.
MSG_PEEK
Просмотр данных без их уничтожения (только для приема).
MSG_OOB
Прием/передача внеочередных данных.
MSG_WAITALL
Не возвращать управление, пока не будет принято запрошенное количество байтов (только для приема).
s.recv_into(buffer [, nbytes [, flags]])
То же, что и recv(), за исключением того, что данные записываются в объ- ект buffer, поддерживающий интерфейс буферов. В аргументе nbytes пере- дается максимальное количество принимаемых байтов. Если этот аргу- мент отсутствует, максимальный размер определяется из размера буфера
buffer
. Аргумент flags имеет тот же смысл, что и в методе recv().
s.recvfrom(bufsize [, flags])
Действует аналогично методу recv(), но возвращает пару значений (data,
address)
, где в поле data возвращается строка с принятыми данными, а в поле address возвращается адрес сокета, отправившего данные. Необяза- тельный аргумент flags имеет тот же смысл, что и в методе recv(). Этот ме- тод в первую очередь предназначен для работы с протоколом UDP.
s.recvfrom_info(buffer [, nbytes [, flags]])
То же, что и recvfrom(), но принимаемые данные сохраняются в объекте
buffer
. Аргумент nbytes определяет максимальное количество принимае- мых байтов. Если этот аргумент отсутствует, максимальный размер опре- деляется из размера буфера buffer. Аргумент flags имеет тот же смысл, что и в методе recv().
s.send(string [, flags])
Посылает данные через сетевое соединение. Необязательный аргумент
flags
имеет тот же смысл, что и в методе recv(). Возвращает количество от- количество от- количество от- от- от- правленных байтов. Это число может оказаться меньше количества байтов в строке string. В случае ошибки возбуждает исключение.
s.sendall(string [, flags])
Посылает данные через сетевое соединение; при этом, прежде чем вернуть управление, пытается отправить все данные. В случае успеха возвращает

Модуль socket
605
None
; в случае ошибки возбуждает исключение. Аргумент flags имеет тот же смысл, что и в методе send().
s.sendto(string [, flags], address)
Посылает данные через сетевое соединение. Необязательный аргумент
flags
имеет тот же смысл, что и в методе recv(). В аргументе address пере- дается кортеж вида (host, port), определяющий адрес удаленного хоста.
К моменту вызова этого метода сокет не должен быть подключен. Возвра- щает количество отправленных байтов. Этот метод в первую очередь пред- назначен для работы с протоколом UDP.
s.setblocking(flag)
Если в аргументе flag передается ноль, сокет переводится в неблокирую- щий режим работы. В противном случае устанавливается блокирующий режим (по умолчанию). При работе в неблокирующем режиме, если вызов метода recv() не находит никаких данных или вызов метода send() не мо- жет немедленно отправить данные, возбуждается исключение socket.er-
.er- er- ror
. При работе в блокирующем режиме вызовы этих методов в подобных обстоятельствах блокируются, пока не появится возможность продолжить работу.
s.setsockopt(level, optname, value)
Устанавливает значение value для параметра option сокета. Аргументы
level
и optname имеют тот же смысл, что и в методе getsockopt(). В аргумен- те value может передаваться целое число или строка, представляющая со- держимое буфера. В последнем случае приложение должно гарантировать, что строка содержит допустимое значение. Перечень допустимых имен па- раметров, их значений и дополнительное описание приводятся в описании метода getsockopt().
s.settimeout(timeout)
Устанавливает предельное время ожидания для операций, выполняемых сокетом. В аргументе timeout передается число с плавающей точкой, опре- деляющее интервал времени в секундах. Значение None означает отсутствие предельного времени ожидания. По истечении указанного предельного времени ожидания операции будут возбуждать исключение socket.timeout.
Вообще говоря, предельное время ожидания должно устанавливаться сра- зу же после создания сокета, так как оно также применяется к операциям, связанным с созданием логического соединения (таким как connect()).
s.shutdown(how)
Отключает одну или обе стороны соединения. Если в аргументе how пере- дается значение 0, дальнейший прием данных будет запрещен. Если в ар- гументе how передается значение 1, будет запрещена дальнейшая переда- ча данных. Если в аргументе how передается значение 2, будут запрещены и прием, и передача данных.
Помимо этих методов экземпляр s сокета обладает следующими свойства- ми, доступными только для чтения, которые соответствуют аргументам функции socket().

606
Глава 21. Работа с сетью и сокеты
Свойство
Описание
s
.family
Семейство адресов сокета (например, AF_INET)
s
.proto
Протокол сокета
s
.type
Тип сокета (например, SOCK_STREAM)
Исключения
Ниже приводится перечень исключений, объявленных в модуле socket.
error
Это исключение возбуждается в случае ошибок, связанных с сетевым со- единением или с адресом. Значением исключения является кортеж (errno, mesg)
, содержащий информацию об ошибке, возвращаемую соответствую- щим системным вызовом. Наследует исключение IOError.
herror
Возбуждается в случае ошибок, связанных с адресом. Значением исключе- ния является кортеж (herrno, hmesg) с числовым кодом ошибки и текстом сообщения. Наследует исключение error.
gaierror
Возбуждается в случае ошибок, связанных с адресом, возникающих в функциях getaddrinfo() и getnameinfo(). Значением исключения является кортеж (errno, mesg), где в поле errno возвращается числовой код ошибки, а в поле mesg – строка с текстом сообщения. В поле errno может возвращать- ся значение одной из следующих констант, объявленных в модуле socket:
Константа
Описание
EAI_ADDRFAMILY
Семейство адресов не поддерживается.
EAI_AGAIN
Временная ошибка при определении адреса по имени хоста.
EAI_BADFLAGS
Недопустимые флаги.
EAI_BADHINTS
Недопустимое рекомендуемое значение.
EAI_FAIL
Критическая ошибка при определении адреса по имени хоста.
EAI_FAMILY
Семейство адресов не поддерживается хостом.
EAI_MEMORY
Ошибка выделения памяти.
EAI_NODATA
Нет ни одного адреса, ассоциированного с именем узла.
EAI_NONAME
Имя узла или имя службы неизвестны.
EAI_PROTOCOL
Протокол не поддерживается.
EAI_SERVICE
Служба с указанным именем не поддерживается сокетом дан- ного типа.
EAI_SOCKTYPE
Указанный тип сокетов не поддерживается.
EAI_SYSTEM
Системная ошибка.

Модуль socket
607
timeout
Возбуждается по истечении предельного времени ожидания. Это исключе- по истечении предельного времени ожидания. Это исключе- по истечении предельного времени ожидания. Это исключе- истечении предельного времени ожидания. Это исключе- истечении предельного времени ожидания. Это исключе- предельного времени ожидания. Это исключе- предельного времени ожидания. Это исключе- времени ожидания. Это исключе- времени ожидания. Это исключе- ожидания. Это исключе- ожидания. Это исключе-
. Это исключе-
Это исключе- ние может возникать только в случае вызова функции setdefaulttimeout() или метода settimeout() объекта сокета. Значением исключения является строка ‘timeout’. Наследует исключение error.
Пример
Во вводной части главы приводился простой пример открытия соединения
TCP. Ниже приводится пример реализации простого эхо-сервера, возвра-
. Ниже приводится пример реализации простого эхо-сервера, возвра- щающего полученные данные, использующего протокол UDP:
# Сервер сообщений, действующий по протоколу UDP
# Принимает небольшие пакеты и отправляет их обратно import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind((“”,10000))
while True:
data, address = s.recvfrom(256)
print(“Получены данные с адреса %s” % str(address))
s.sendto(b”echo:” + data, address)
Ниже приводится пример клиента, отправляющего сообщения серверу, реализация которого приводится выше:
# Клиент сообщений, действующий по протоколу UDP
import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(b”Hello World”, (“”, 10000))
resp, addr = s.recvfrom(256)
print(resp)
s.sendto(b”Spam”, (“”, 10000))
resp, addr = s.recvfrom(256)
print(resp)
s.close()
Примечания
• Не все константы и параметры сокетов доступны во всех платформах.
Если перед вами стоит цель обеспечить переносимость программ, вы должны использовать только те параметры, которые описываются в ис- точниках, таких как книга У. Ричарда Стивенса (W. Richard Stevens)
«UNIX Network Programming»,
1
упоминавшаяся в начале этого раздела.
• Обратите внимание на отсутствие в модуле socket системных вызовов recvmsg()
и sendmsg(), которые обычно используются для работы со вспо- могательными данными и дополнительными сетевыми параметрами, имеющими отношение к заголовкам пакетов, маршрутизации и другим особенностям. Чтобы получить эту функциональность, можно восполь-
1
Стивенс У. «UNIX. Разработка сетевых приложений». – Пер. с англ. – СПб.: Пи- тер, 2003.

608
Глава 21. Работа с сетью и сокеты зоваться сторонними модулями, такими как PyXAPI (http://pypi.python.
org/pypi/PyXAPI
).
• Между операциями, выполняющимися в неблокирующем режиме, и операциями, предусматривающими выход по истечении предельного ожидания, существует важное отличие. Когда метод сокета выполняет- ся в неблокирующем режиме, он возвращает управление немедленно, с признаком ошибки, если операция может быть заблокирована. Когда определено предельное время ожидания, методы возвращают признак ошибки, только если операция не была выполнена в течение указанного интервала времени.
Модуль ssl
Модуль ssl используется, чтобы обертывать объекты сокетов протоколом безопасных соединений (Secure Sockets Layer, SSL), который обеспечи- вает шифрование данных и аутентификацию. Реализация этого модуля опирается на использование библиотеки OpenSSL (http://www.openssl.org).
Полное обсуждение теории и практики применения SSL выходит далеко за рамки этого раздела. Поэтому здесь будут рассмотрены только самые основные приемы использования этого модуля; при этом предполагается, что вы знакомы с настройкой SSL, с ключами, сертификатами и другими особенностями:
wrap_socket(sock [, **opts])
Обертывает существующий сокет sock (созданный средствами модуля sock- et
) поддержкой SSL и возвращает экземпляр класса SSLSocket. Эта функция должна вызываться перед вызовом метода connect() или accept(). В аргу- менте opts передаются именованные аргументы, определяющие дополни- тельные параметры настройки.
Именованный
аргумент
Описание
server_side
Логический флаг, который определяет, будет ли сокет высту- пать в роли сервера (True) или клиента (False). По умолчанию используется значение False.
keyfile
Файл ключа, используемый для идентификации локальной сто- ключа, используемый для идентификации локальной сто- ключа, используемый для идентификации локальной сто-
, используемый для идентификации локальной сто- используемый для идентификации локальной сто- для идентификации локальной сто- для идентификации локальной сто- идентификации локальной сто- идентификации локальной сто- локальной сто- локальной сто- сто- сто- роны соединения. Это должен быть файл в формате PEM и обыч- соединения. Это должен быть файл в формате PEM и обыч- соединения. Это должен быть файл в формате PEM и обыч-
. Это должен быть файл в формате PEM и обыч-
Это должен быть файл в формате PEM и обыч-
PEM и обыч- и обыч- но этот параметр используется, если в параметре certfile указан файл, в котором отсутствует ключ.
certfile
Файл сертификата, используемый для идентификации локаль- ной стороны соединения. Это должен быть файл в формате PEM.
cert_reqs
Определяет, должен ли файл сертификата запрашиваться у другой стороны соединения и должен ли он быть проверен.
Значение CERT_NONE означает, что сертификат не требуется, CERT_
OPTIONAL
– сертификат не требуется, но при его получении он бу- дет проверен, а значение CERT_REQUIRED означает, что сертификат обязателен и будет проверен. Если предполагается проверка сер- тификата, также должен быть установлен параметр ca_certs.

Модуль ssl
609
ca_certs
Имя файла, где хранится сертификат центра сертификации, ко- торый будет использоваться для проверки.
ssl_version
Используемая версия протокола SSL. Возможные значения:
PROTOCOL_TLSv1
, PROTOCOL_SSLv2, PROTOCOL_SSLv23 и PROTOCOL_SSLv3. По умолчанию используется версия протокола PROTOCOL_SSLv3
do_handshake_
on_connect
Логический флаг, который определяет, будет ли процедура под- ключения по протоколу SSL выполняться автоматически. По умолчанию используется значение True.
suppress_
ragged_eofs
Определяет, как функция read() будет обрабатывать неожидан- ное получение признака конца файла. Если указано значение
True
(по умолчанию), будет возвращаться признак конца файла.
Если указано значение False, будет возбуждаться исключение.
Экземпляр s класса SSLSocket, наследующего класс socket.socket, поддер- живает следующие операции:
s.cipher()
Возвращает кортеж (name, version, secretbits), где в поле name возвращается название используемого алгоритма шифрования, в поле version возвраща- ется версия протокола SSL и в поле secretbits – длина используемого ключа шифрования в битах.
s.do_handshake()
Выполняет начальный этап соединения SSL. Обычно этот метод вызывает-
SSL. Обычно этот метод вызывает-
. Обычно этот метод вызывает- ся автоматически, если только функции wrap_socket() не был передан име- нованный аргумент do_handshake_on_connect со значением False. Если для са- мого сокета s был установлен неблокирующий режим работы, возбуждает исключение SSLError в случае невозможности завершить операцию. В атри- буте e.args[0] экземпляра исключения SSLError будет возвращено значение
SSL_ERROR_WANT_READ
или SSL_ERROR_WANT_WRITE, в зависимости от того, какая операция должна быть выполнена. Чтобы продолжить начальную проце- дуру подключения после того, как операция чтения или записи сможет быть выполнена, достаточно просто еще раз вызвать метод s.do_handshake().
s.getpeercert([binary_form])
Возвращает сертификат другого конца соединения, если таковой имеется.
В случае отсутствия сертификата возвращает None. Если сертификат имеет- ся, но он не прошел проверку, возвращается пустой словарь. Если был при- нят сертификат и проверка его увенчалась успехом, возвращается словарь с ключами ‘subject’ и ‘notAfter’. Если в аргументе binary_form передается значение True, сертификат возвращается в виде последовательности байтов в формате DER.
s.read([nbytes])
Читает до nbytes байтов данных и возвращает их. При вызове без аргумента
nbytes
читает до 1024 байтов.
s.write(data)
Записывает строку байтов data. Возвращает количество фактически запи- санных байтов.

610
Глава 21. Работа с сетью и сокеты
s.unwrap()
Закрывает соединение SSL и возвращает объект сокета, который далее мо-
SSL и возвращает объект сокета, который далее мо- и возвращает объект сокета, который далее мо- жет использоваться для обмена незашифрованными данными.
Ниже перечислены вспомогательные функции, объявленные в модуле:
cert_time_to_seconds(timestring)
Преобразует строку timestring из формата, используемого в сертификатах, в число с плавающей точкой, совместимое с функцией time.time().
DER_cert_to_PEM_cert(derbytes)
Принимает строку байтов derbytes с сертификатом в формате DER и возвра-
DER и возвра- и возвра- щает строку с версией сертификата в формате PEM.
PEM_cert_to_DER_cert(pemstring)
Принимает строку pemstring с сертификатом в формате PEM и возвращает строку байтов с версией сертификата в формате DER.
get_server_certificate(addr [, ssl_version [, ca_certs]])
Извлекает сертификат сервера SSL и возвращает в виде строки в формате
PEM. В аргументе addr передается адрес сервера в виде (hostname, port).
В аргументе ssl_version передается номер версии протокола SSL, а в аргу-
SSL, а в аргу-
, а в аргу- менте ca_certs – имя файла с сертификатом центра сертификации, как опи- сывалось в описании функции wrap_socket().
RAND_status()
Возвращает True, если с точки зрения SSL генератор псевдослучайных чи-
SSL генератор псевдослучайных чи- генератор псевдослучайных чи- сел обеспечивает достаточный уровень случайности.
RAND_egd(path)
Читает 256 случайных байтов из демона энтропии и добавляет их в генера- тор псевдослучайных чисел. Аргумент path определяет имя сокета демона.
RAND_add(bytes, entropy)
Добавляет байты из строки байтов bytes в генератор псевдослучайных чи- в генератор псевдослучайных чи- генератор псевдослучайных чи- генератор псевдослучайных чи- псевдослучайных чи- псевдослучайных чи- чи- чи- сел. В аргументе entropy передается неотрицательное число с плавающей точкой, определяющее нижнюю границу энтропии.
Примеры
Следующий пример демонстрирует, как с помощью этого модуля можно от- крыть SSL-соединение со стороны клиента:
import socket, ssl
ёё
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_s = ssl.wrap_socket(s)
ssl_s.connect((‘gmail.google.com’,443))
print(ssl_s.cipher())
ёё
# Отправить запрос ssl_s.write(b”GET / HTTP/1.0\r\n\r\n”)
ёё

Модуль SocketServer
611
# Получить ответ while True:
data = ssl_s.read()
if not data: break print(data)
ssl_s.close()
Н
иже приводится пример сервера времени, действующего по протоколу
SSL:
import socket, ssl, time
ёё
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
s.bind((‘’,12345))
s.listen(5)
ёё
while True:
client, addr = s.accept() # Принять соединение print “Получен запрос на соединение с “, addr client_ssl = ssl.wrap_socket(client,
server_side=True,
certfile=”timecert.pem”)
client_ssl.sendall(b”HTTP/1.0 200 OK\r\n”)
client_ssl.sendall(b”Connection: Close\r\n”)
client_ssl.sendall(b”Content-type: text/plain\r\n\r\n”)
resp = time.ctime() + “\r\n”
client_ssl.sendall(resp.encode(‘latin-1’))
client_ssl.close()
client.close()
Чтобы запустить этот сервер, необходимо сохранить подписанный серти- фикат в файле timecert.pem. Этот сертификат можно создать с помощью ко- манды UNIX:
% openssl req –new –x509 –days 30 –nodes –out timecert.pem –keyout timecert.pem
Чтобы протестировать работу этого сервера, попробуйте соединиться с ним с помощью веб-броузера, указав адрес URL ‘https://localhost:1234’. Если все работает, броузер выведет предупреждение о том, что используется са- моподписанный сертификат. После того как вы согласитесь продолжить, в окне броузера появится вывод, полученный от сервера.
Модуль SocketServer
В Python 3 этот модуль называется socketserver. Модуль SocketServer объ- являет классы, упрощающие реализацию серверов на основе сокетов TCP,
UDP и домена UNIX.
Обработчики
Для использования модуля необходимо объявить класс обработчика, про- изводный от базового класса BaseRequestHandler. Экземпляр h класса Base-

612
Глава 21. Работа с сетью и сокеты
RequestHandler реализует один или более методов из тех, что перечислены ниже:
h.finish()
Вызывается для выполнения завершающих операций после того, как ме- тод handle() закончит работу. По умолчанию этот метод ничего не делает.
Он не вызывается, если метод setup() или handle() возбуждает исключение.
h.handle()
Этот метод выполняет фактическую работу в соответствии с запросом. Он вызывается без аргументов, но может использовать некоторые атрибуты экземпляра для получения необходимой информации. Атрибут h.request содержит запрос, h.client_address – адрес клиента и h.server – экземпляр сервера, вызвавшего обработчик. Для потоков, таких как TCP, атрибут
h.request будет содержать объект сокета. Для дейтаграмм он будет содер- жать строку байтов с принятыми данными.
h.setup()
Этот метод вызывается перед методом handle() для выполнения операций по инициализации. По умолчанию этот метод ничего не делает. Если не- умолчанию этот метод ничего не делает. Если не- умолчанию этот метод ничего не делает. Если не- этот метод ничего не делает. Если не- этот метод ничего не делает. Если не- метод ничего не делает. Если не- метод ничего не делает. Если не- ничего не делает. Если не- ничего не делает. Если не- не делает. Если не- не делает. Если не- делает. Если не- делает. Если не-
. Если не-
Если не- обходимо реализовать в сервере дополнительные настройки соединения, такие как подключение по протоколу SSL, эти операции должны быть реа-
SSL, эти операции должны быть реа-
, эти операции должны быть реа- лизованы в этом методе.
Ниже приводится пример класса обработчика, реализующего простой сер- вер времени, который может работать как с потоками, так и с дейтаграм- мами:
try:
from socketserver import BaseRequestHandler # Python 3
except ImportError:
from SocketServer import BaseRequestHandler # Python 2
import socket import time
ёё
class TimeServer(BaseRequestHandler):
def handle(self):
resp = time.ctime() + “\r\n”
if isinstance(self.request,socket.socket):
# Работа с потоком self.request.sendall(resp.encode(‘latin-1’))
else:
# Работа с дейтаграммой self.server.socket.sendto(resp.encode(‘latin-1’), self.client_address)
Если заранее известно, что обработчик будет работать только с потоковыми протоколами, такими как TCP, в качестве родительского можно использо-
TCP, в качестве родительского можно использо-
, в качестве родительского можно использо- вать класс StreamRequestHandler, а не BaseRequestHandler. Этот класс опреде- ляет два атрибута: h.wfile – объект, похожий на файл, который отправляет данные клиенту, и h.rfile – объект, похожий на файл, позволяющий при- нимать данные от клиента. Например:

Модуль SocketServer
613
try:
from socketserver import StreamRequestHandler # Python 3
except ImportError:
from SocketServer import StreamRequestHandler # Python 2
import time
ёё
class TimeServer(StreamRequestHandler):
def handle(self):
resp = time.ctime() + “\r\n”
self.wfile.write(resp.encode(‘latin-1’))
Е
сли обработчик должен работать только с отдельными пакетами и всегда возвращать ответ отправителю, в качестве родительского можно исполь- зовать класс DatagramRequestHandler вместо BaseRequestHandler. Этот класс реализует тот же интерфейс файлов, что и класс StreamRequestHandler. На- пример:
try:
from socketserver import DatagramRequestHandler # Python 3
except ImportError:
from SocketServer import DatagramRequestHandler # Python 2
import time
ёё
class TimeServer(DatagramRequestHandler):
def handle(self):
resp = time.ctime() + “\r\n”
self.wfile.write(resp.encode(‘latin-1’)
В данном случае все данные, записанные в self.wfile, собираются в единый пакет, который отправляется клиенту по завершении работы метода han- dle()
Серверы
Чтобы задействовать обработчик, его необходимо подключить к объекту сервера. В модуле объявлено четыре основных класса серверов:
TCPServer(address, handler)
Сервер, поддерживающий протокол TCP IPv4. В аргументе address переда- переда- ется кортеж вида (host, port). В аргументе handler – экземпляр подкласса класса BaseRequestHandler, описанного выше.
UDPServer(address, handler)
Сервер, поддерживающий протокол UDP IPv4. Аргументы address и handler имеют тот же смысл, что и в конструкторе TCPServer().
UnixStreamServer(address, handler)
Сервер, реализующий потоковый протокол с использованием сокетов до- мена UNIX. Наследует класс TCPServer.
UnixDatagramServer(address, handler)
Сервер, поддерживающий протокол дейтаграмм с использованием сокетов домена UNIX. Наследует класс UDPServer.

614
Глава 21. Работа с сетью и сокеты
Э
кземпляры всех четырех классов серверов обладают следующими основ- ными методами:
s.fileno()
Возвращает целочисленный дескриптор файла серверного сокета. Наличие этого метода обеспечивает возможность использовать экземпляры серве- ров в операциях опроса, таких как функция select().
s.serve_forever()
Обслуживает неограниченное число запросов.
s.shutdown()
Останавливает цикл serve_forever().
Следующие атрибуты позволяют получать некоторую основную информа- цию о настройках действующего сервера:
s.RequestHandlerClass
Пользовательский класс обработчика, который был передан конструктору сервера.
s.server_address
Адрес, на котором сервер ожидает получения запросов от клиентов, напри- мер такой кортеж: (‘127.0.0.1’, 80).
s.socket
Объект сокета, используемый для приема входящих запросов.
Ниже приводится пример использования экземпляра класса TimeHandler в составе сервера TCP:
from SocketServer import TCPServer
ёё
serv = TCPServer((‘’,10000,TimeHandler)
serv.serve_forever()
Ниже приводится пример использования обработчика в составе сервера
UDP:
from SocketServer import UDPServer
ёё
serv = UDPServer((‘’,10000,TimeHandler)
serv.serve_forever()
Ключевым аспектом модуля SocketServer является обособленность обработ- чиков от серверов. То есть один и тот же обработчик можно подключить к серверам самых разных типов, не меняя его реализацию.
Определение собственных серверов
Зачастую для серверов требуется определять различные параметры на- стройки, чтобы учесть такие особенности, как различные семейства адре- сов, предельное время ожидания, многозадачность и другие. Для этого не- обходимо определить свой класс, производный от одного из четырех базо-

Модуль SocketServer
615
вых классов серверов, описанных в предыдущем разделе. Для настройки параметров сокета, составляющего основу сервера, могут быть определены следующие атрибуты класса:
Server.address_family
Семейство адресов, используемое сокетом сервера. По умолчанию исполь- зуется значение socket.AF_INET. Если необходимо обеспечить поддержку
IPv6, следует использовать значение socket.AF_INET6.
Server.allow_reuse_address
Логический флаг, разрешающий или запрещающий повторное исполь- зование адреса сокета. Это бывает удобно, когда необходимо быстро пере- запустить сервер на том же порту, после того как программа завершится
(в противном случае придется ожидать несколько минут). По умолчанию используется значение False.
Server.request_queue_size
Размер очереди запросов, который передается методу listen() сокета. По умолчанию используется значение 5.
Server.socket_type
Тип сокета, используемого сервером, такой как socket.SOCK_STREAM или sock- et.SOCK_DGRAM
Server.timeout
Предельное время ожидания в секундах, в течение которого сервер будет ожидать поступления новых запросов. По истечении этого интервала вре- мени будет вызываться метод handle_timeout() сервера (описывается ниже), после чего сервер опять возвращается к ожиданию. Это значение не исполь-
зуется
для установки предельного времени ожидания в сокете. Однако если для сокета было определено предельное время ожидания, вместо этого значения будет использоваться значение из сокета.
Ниже приводится пример создания сервера, который позволяет повторно использовать номер порта:
from SocketServer import TCPServer
ёё
class TimeServer(TCPServer):
allow_reuse_address = True
ёё
serv = TimeServer((‘’,10000,TimeHandler)
serv.serve_forever()
При желании в классах, производных от базовых классов серверов, можно переопределять следующие методы. Если вы будете переопределять какой- либо из этих методов, не забудьте вызвать одноименный метод суперкласса.
Server.activate()
Выполняет операцию listen() на стороне сервера. Сокет сервера доступен в виде атрибута self.socket.

616
Глава 21. Работа с сетью и сокеты
Server.bind()
Выполняет операцию bind() на стороне сервера.
Server.handle_error(request, client_address)
Обрабатывает неперехваченные исключения, которые возникают в процес- се работы. Для получения информации о последнем исключении следует использовать функцию sys.exc_info() или функции из модуля traceback.
Server.handle_timeout()
Обрабатывает ситуации, когда операции завершаются по истечении пре- дельного времени ожидания. Переопределяя этот метод и изменяя значе- ние предельного времени ожидания, можно в цикл событий сервера инте- грировать дополнительные операции.
Server.verify_request(request, client_address)
Этот метод можно переопределить, чтобы реализовать проверку соедине- ния перед обработкой запроса. Это может быть реализация сетевой защи- ты или каких-то других проверок.
Наконец, дополнительные возможности сервера можно получить за счет использования классов-примесей. С их помощью может быть добавлена многозадачность, реализованная на основе потоков управления или дочер- них процессов. Для этой цели определены следующие классы:
ForkingMixIn
Класс-примесь, который в UNIX создает дочерние процессы сервера, по-
UNIX создает дочерние процессы сервера, по- создает дочерние процессы сервера, по- зволяя одновременно обслуживать множество клиентов. Атрибут класса max_children определяет максимальное количество дочерних процессов, а атрибут класса timeout определяет интервал времени, через который бу- дут выполняться попытки ликвидировать процессы-зомби. Атрибут экзем- пляра active_children содержит количество активных процессов.
ThreadingMixIn
Класс-примесь, который модифицирует сервер так, что он создает новые потоки управления, позволяя одновременно обслуживать множество кли- ентов. Этот класс не имеет ограничений на количество создаваемых пото- ков управления. По умолчанию создаются недемонические потоки, если в атрибут класса daemon_threads не записать значение True.
Чтобы добавить к серверу эти возможности, следует использовать меха- низм множественного наследования и класс-примесь указывать первым в списке. Например, ниже приводится пример сервера времени, запускаю- щего дочерние процессы:
from SocketServer import TCPServer, ForkingMixIn
ёё
class TimeServer(ForkingMixIn, TCPServer):
allow_reuse_address = True max_children = 10
ёё
serv = TimeServer((‘’,10000,TimeHandler)
serv.serve_forever()

Модуль SocketServer
617
Поскольку ситуация, когда параллельно выполняется несколько серверов, достаточно типична, для этой ситуации в модуле SocketServer предопреде- лены следующие классы серверов.
• ForkingUDPServer(address, handler)
• ForkingTCPServer(address, handler)
• ThreadingUDPServer(address, handler)
• ThreadingTCPServer(address, handler)
В действительности эти классы объявлены, как производные классы от классов-примесей и классов серверов. В качестве примера ниже приводит- ся объявление класса ForkingTCPServer:
class ForkingTCPServer(ForkingMixIn, TCPServer): pass
Создание собственных серверов приложений
Класс SocketServer часто используется другими модулями из стандартной библиотеки для реализации серверов, работающих с прикладными прото- колами, такими как HTTP и XML-RPC. Функциональность этих серверов также можно приспосабливать под свои нужды через множественное на- следование и переопределение методов, объявленных в базовых классах.
Например, ниже приводится сервер XML-RPC, порождающий дочерние процессы, который принимает только соединения, исходящие с петлевого
(loopback) интерфейса:
try:
from xmlrpc.server import SimpleXMLRPCServer # Python 3
from socketserver import ForkingMixIn except ImportError: # Python 2
from SimpleXMLRPCServer import SimpleXMLRPCServer from SocketServer import ForkingMixIn
ёё
class MyXMLRPCServer(ForkingMixIn,SimpleXMLRPCServer):
def verify_request(self, request, client_address):
host, port = client_address if host != ‘127.0.0.1’:
return False return SimpleXMLRPCServer.verify_request(self,request,client_address)
ёё
# Пример использования def add(x,y):
return x+y server = MyXMLRPCServer((“”,45000))
server.register_function(add)
server.serve_forever()
Чтобы опробовать этот пример, необходимо импортировать модуль xmlrp- clib
. Запустите сервер, реализация которого представлена выше, а затем запустите отдельный процесс интерпретатора Python:
>>> import xmlrpclib
>>> s = xmlrpclib.ServerProxy(“http://localhost:45000”)

618
Глава 21. Работа с сетью и сокеты
>>> s.add(3,4)
7
>>>
Чтобы убедиться, что сервер отвергает попытки соединения с другого адре- са, попробуйте выполнить тот же код на другом компьютере в сети. Для этого замените строку “localhost” сетевым именем компьютера, на котором запущен сервер.

1   ...   50   51   52   53   54   55   56   57   ...   82


написать администратору сайта