Чтение онлайн

ЖАНРЫ

Язык программирования Python
Шрифт:

Модуль socket обеспечивает возможность работать с сокетами из Python. Сокеты используют транспортный уровень согласно семиуровневой модели OSI (Open Systems Interconnection, взаимодействие открытых систем), то есть относятся к более низкому уровню, чем большинство описываемых в этом разделе протоколов.

Уровни модели OSI:

Физический

Поток битов, передаваемых по физической линии. Определяет параметры физической линии.

Канальный (Ethernet, PPP, ATM и т.п.)

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

физически единой сети.

Сетевой (IP)

Маршрутизирует информационные пакеты от узла к узлу.

Транспортный (TCP, UDP и т.п.)

Обеспечивает прозрачную передачу данных между двумя точками соединения.

Сеансовый

Управляет сеансом соединения между участниками сети. Начинает, координирует и завершает соединения.

Представления

Обеспечивает независимость данных от формы их представления путем преобразования форматов. На этом уровне может выполняться прозрачное (с точки зрения вышележащего уровня) шифрование и дешифрование данных.

Приложений (HTTP, FTP, SMTP, NNTP, POP3, IMAP и т.д.)

Поддерживает конкретные сетевые приложения. Протокол зависит от типа сервиса.

Каждый сокет относится к одному из коммуникационных доменов. Модуль socket поддерживает домены UNIX и Internet. Каждый домен подразумевает свое семейство протоколов и адресацию. Данное изложение будет затрагивать только домен Internet, а именно протоколы TCP/IP и UDP/IP, поэтому для указания коммуникационного домена при создании сокета будет указываться константа socket.AF_INET.

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

Сервер:

Листинг

import socket, string

def do_something(x):

lst = map(None, x);

lst.reverse;

return string.join(lst, "")

HOST = "" # localhost

PORT = 33333

srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

srv.bind((HOST, PORT))

while 1:

print «Слушаю порт 33333»

srv.listen(1)

sock, addr = srv.accept

while 1:

pal = sock.recv(1024)

if not pal:

break

print «Получено от %s:%s:" % addr, pal

lap = do_something(pal)

print «Отправлено %s:%s:" % addr, lap

sock.send(lap)

sock.close

Клиент:

Листинг

import socket

HOST = "" # удаленный компьютер (localhost)

PORT = 33333 # порт на удаленном компьютере

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock.connect((HOST, PORT))

sock.send(«ПАЛИНДРОМ»)

result = sock.recv(1024)

sock.close

print «Получено:", result

Примечание:

В примере использованы русские буквы: необходимо указывать кодировку.

Прежде всего, нужно запустить сервер. Сервер открывает сокет на локальной машине на порту 33333, и адресе 127.0.0.1. После этого он слушает (listen) порт. Когда на порту появляются данные, принимается (accept) входящее соединение. Метод accept возвращает

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

Код программы–клиента достаточно очевиден. Метод connect устанавливает соединение с удаленным хостом (в приведенном примере он расположен на той же машине). Данные передаются методом send и принимаются методом recv — аналогично тому, что происходит на сервере.

Модуль socket имеет несколько вспомогательных функций. В частности, функции для работы с системой доменных имен (DNS):

Листинг

>>> import socket

>>> socket.gethostbyaddr('www.onego.ru')

('www.onego.ru', [], ['195.161.136.4'])

>>> socket.gethostbyaddr('195.161.136.4')

('www.onego.ru', [], ['195.161.136.4'])

>>> socket.gethostname

'rnd.onego.ru'

В новых версиях Python появилась такая функция как socket.getservbyname. Она позволяет преобразовывать наименования Интернет–сервисов в общепринятые номера портов:

Листинг

>>> for srv in 'http', 'ftp', 'imap', 'pop3', 'smtp':

… print socket.getservbyname(srv, 'tcp'), srv

80 http

21 ftp

143 imap

110 pop3

25 smtp

Модуль также содержит большое количество констант для указания протоколов, типов сокетов, коммуникационных доменов и т.п. Другие функции модуля socket можно при необходимости изучить по документации.

Модуль smtplib

Сообщения электронной почты в Интернете передаются от клиента к серверу и между серверами в основном по протоколу SMTP (Simple Mail Transfer Protocol, простой протокол передачи почты). Протокол SMTP и ESMTP (расширенный вариант SMTP) описаны в RFC 821 и RFC 1869. Для работы с SMTP в стандартной библиотеке модулей имеется модуль smtplib. Для того чтобы начать SMTP–соединение с сервером электронной почты, необходимо в начале создать объект для управления SMTP–сессией с помощью конструктора класса SMTP:

Листинг

smtplib.SMTP([host[, port]])

Параметры host и port задают адрес и порт SMTP–сервера, через который будет отправляться почта. По умолчанию, port=25. Если host задан, конструктор сам установит соединение, иначе придется отдельно вызывать метод connect. Экземпляры класса SMTP имеют методы для всех распространенных команд SMTP–протокола, но для отправки почты достаточно вызова конструктора и методов sendmail и quit:

Листинг

# -*- coding: cp1251 -*-from smtplib import SMTP

fromaddr = «student@mail.ru» # От кого

toaddr = «rnd@onego.ru» # Кому

message = ""«From: Student <%(fromaddr)s>

To: Lecturer <%(toaddr)s>

Subject: From Python course student

MIME–Version: 1.0

Content–Type: text/plain; charset=Windows–1251

Content–Transfer–Encoding: 8bit

Здравствуйте! Я изучаю курс по языку Python и

отправляю письмо его автору.

"""

connect = SMTP('mail.onego.ru')

connect.set_debuglevel(1)

Поделиться с друзьями: