Дріс Python-даы желілік осымшалар
Сокеталармен жмыс
IP-желілерде олданылатын клиент-сервер архитектурасы IP-пакеттерді клиенттер мен сервер арасындаы байланыс шін пайдаланылады. Клиент серверге срау жібереді, ол жауап береді. TCP/IP жадайында клиент жне сервер арасында байланыс орнатылады (детте екі жаты мліметтерді жіберумен), ал UDP/IP жадайында – клиент жне сервер кепілді емес пакеттермен (дейтаграммалармен) алмасады.
рбір IP-желілеріндегі желілік интерфейс осы желіде бірегей адресі ( IP-адрес) бар. Ышамдап айтанда Интернет желісіндегі р компьютерде зіні IP-адресі болады. Сонымен атар бір желілік интерфейсте бірнеше желілік порттар болуы ммкін. Клиент осымшасына желілік байланыс орнату шін бос портты тадау жне шірілген желілік интерфейсте аныталан нмерлер портын тындайтын (listen) серверлік осымшамен байланысын орнату керек. IP-адрес жбы жне порт сокет (я) –желілік байланысты бастапы (соы) нктесін сипаттайды. TCP/IP байланысын ру шін екі сокет керек: бірі жергілікті машинаа, ал басасы – шірілгенге. Осылайша, рбір желілік байланысты IP-адресі жне жергілікті машинадаы порты, сонымен атар IP-адресі жне шірілген машинадаы порты бар.
Socket модулі Python-даы сокеттермен жмыс істеу ммкіндігін амтамасыз етеді.
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() дісі, байланыс орнатылып жатан (Ip-адрес жбы, ашытытаы машинада орналасан порт), Socket-объектісі жне ашытытаы компьютерді адресіні жптарын айтарады. Осыдан кейін клиенттермен тілдесу шін 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)
connect.sendmail(fromaddr, toaddr, message % vars())
connect.quit()
Ескере кететіні, toaddr хабарламада (To рісінде) жне жіберілуде сйкес келмеуі ммкін. Мселесінде абылдаушы жне жіберуші SMTP-сессияларында SMTP-хаттамасыны командаларымен жіберіледі. Жоарыда келтірілген мысалды жібергенде экранда дрысталан млімет шыады (дрысталу дегейі 1-ге те етіліп берген):
send: 'ehlo rnd.onego.ru\r\n'
reply: '250-mail.onego.ru Hello as3-042.dialup.onego.ru [195.161.147.4],
pleased to meet you\r\n'
send: 'mail FROM:<student@mail.ru> size=270\r\n'
reply: '250 2.1.0 <student@mail.ru>... Sender ok\r\n'
send: 'rcpt TO:<rnd@onego.ru>\r\n'
reply: '250 2.1.5 <rnd@onego.ru>... Recipient ok\r\n'
send: 'data\r\n'
reply: '354 Enter mail, end with "." on a line by itself\r\n'
send: 'From: Student <student@mail.ru>\r\n . . . '
reply: '250 2.0.0 iBPFgQ7q028433 Message accepted for delivery\r\n'
send: 'quit\r\n'
reply: '221 2.0.0 mail.onego.ru closing connection\r\n'
Бл (біршама ысартылан) дрысталан мліметтен клиент командаларды SMTP-серверіне (EHLO, MAIL FROM, RCPT TO, DATA, QUIT), жіберілгенін(send) круге болады, ал анау, айтарылым кодын айтара отырып командаларды орындайды жне жауап береді (reply).
SMTP-сессиясыны орындалу кезінде бірнеше хаттарды бірден жіберуге болады, егер quit ( ) шаырмаса.
Негізінде, SMTP командаларын блекте беруге болады: бл шін байланыс обьектісіні, SMTP-хаттамасыны бір атты командаларымен сйкес келетін, дістері бар (helo(), ehlo(), expn(), help(), mail(), rcpt(), vrfy(), send(), noop(), data()).
docmd() дісіні кмегімен SMTP-серверіне ерікті командасында беруге болады. Келесі мысалда, кімде-кім уаыт те келе кейбір домендер шін кезекті хабарлама саталатын почталы серверден SMTP хаттамасы бойынша з серверіне почтаны абылдайтындар олдана алатын, арапайым сценарийі крсетілген:
from smtplib import SMTP
connect = SMTP('mx.abcde.ru')
connect.set_debuglevel(1)
connect.docmd("ETRN rnd.abcde.ru")
connect.quit()
Бл арапайым сценарий mx.abcde.ru серверіне rnd.abcde.ru доменіндегі негізгі почталы сервермен байланысуа рекет жасап круін сынады жне барлы оан жинаталан почтаны жібереді.
smtplib.SMTP классымен жмыс кезінде трлі ерекше жадайлар туындауы ммкін. Оларды кейбір таайындалулары тменде келтірілген:
smtplib.SMTPException
Барлы модулдерді ерекше жадайына базалы класс.
smtplib.SMTPServerDisconnected
Сервер аяастынан байланысты зді (немесе сервермен байланыс орнатылмаан).
smtplib.SMTPResponseException
SMTP-сервер жауабыны кодына ие барлы ерекше жадай шін базалы класс.
smtplib.SMTPSenderRefused
Жiберушiнi абылдамайды
smtplib.SMTPRecipientsRefused
Барлы алушылар сервермен абылданбаан.
smtplib.SMTPDataError
Сервер берілген хабарламаа белгісіз кодпен жауап берді.
smtplib.SMTPConnectError
Байланыс орнату кезіндегі ате.
smtplib.SMTPHeloError
Сервер HELO командасына дрыс жауап бермеді немесе оны абылдамады.
Poplib модулі
Таыда бір хаттама - POP3 (Post Office Protocol, почталы хаттама) – серверде почталы жшіктен почта абылдау шін ызмет етеді (хаттама RFC 1725 аныталан).
Почталы сервермен жмыс істеу шін олармен байланыс орнату керек жне, жоарыда аралан мысал трізді, SMTP-командасыны кмегімен талап етілген хабарламаларды алу. POP3 байланыс обьектісімен poplib модуліндегі POP3 конструктор классы арылы орнатуа болады:
poplib.POP3(host[, port])
Мндаы host - POP3-серверіні адресі, port - сервердегі порт (нсіз келісім бойынша 110), pop_obj- POP3-серверімен жмыс сеансын басару шін обьекті.
Келесі мысал POP3-байланысымен жмыс істеу шін негізгі дістерді крсетеді.
import poplib, email
# олданушыны есептiк деректерi:
SERVER = "pop.server.com"
USERNAME = "user"
USERPASSWORD = "secretword"
p = poplib.POP3(SERVER)
print p.getwelcome()
# бiрдейлендiрудi кезеi
print p.user(USERNAME)
print p.pass_(USERPASSWORD)
# транзакциялау кезеі
response, lst, octets = p.list()
print response
for msgnum, msgsize in [i.split() for i in lst]:
print "Сообщение %(msgnum)s имеет длину %(msgsize)s" % vars()
print "UIDL =", p.uidl(int(msgnum)).split()[2]
if int(msgsize) > 32000:
(resp, lines, octets) = p.top(msgnum, 0)
else:
(resp, lines, octets) = p.retr(msgnum)
msgtxt = "\n".join(lines)+"\n\n"
msg = email.message_from_string(msgtxt)
print "* От: %(from)s\n* Кому: %(to)s\n* Тема: %(subject)s\n" % msg
# msg содержит заголовки сообщения или все сообщение (если оно небольшое)
# этап обновления
print p.quit()
Ескерту:
лбетте, мысал наты істеу шін наты есептік деректерді енгізу керек.
Сценарий орындалу кезде экрана келесідей шыарады:
+OK POP3 pop.server.com server ready
+OK User name accepted, password please
+OK Mailbox open, 68 messages
+OK Mailbox scan listing follows
Сообщение 1 имеет длину 4202
UIDL = 4152a47e00000004
* От: online@kaspersky.com
* Кому: user@server.com
* Тема: KL Online Activation
...
+OK Sayonara
Осы жне баса POP3 классыны кшірмелеріні дістері тменде сипатталан:
діс | POP3 командасы | сипатталуы |
getwelcome() | POP3-сервері бойынша s жолын алады. | |
user(name) | USER name | name олданушы атымен крсетілген USER командасын жібереді. |
pass_(pwd) | PASS pwd | PASS командасында олданушы кілттік сзін жібереді. Осы командадан кейін жне QUIT командасыны орындалуына дейін почталы жшік батталады. |
apop(user, secret) | APOP user secret | APOP бойынша серверде идентификациялау. |
rpop(user) | RPOP user | RPOP дісі бойынша идентификациялау |
stat() | STAT | Пошта жшiгi туралы апаратпен кортежді айтарады. Мндаы m – хабарлама саны, l – байт бойынша почта жшігіні лшемі. |
list([num]) | LIST [num] | (resp, ['num octets', ...]) форматтаы хабарлама тізімін айтарады, егер num, и "+OK num octets" крсетілмесе, егер крсетілсе. |
retr(num) | RETR num | Серверден num нмерімен берілген хабарламаны жктейді жне (resp, lst, octets) серверіні жауабымен берілген кортежді айтарады |
dele(num) | DELE num | Num нмерімен берілген хабарламаны шіреді |
rset() | RSET | Хабарламаны шіру белгілерін болдырмайды. |
noop() | NOOP | Ештене істемейді (байланысуды олдайды) |
quit() | QUIT | Серверден шірілу. Сервер барлы ажетті згертулерді орындайды (хабарламаны шіреді) жне почталы жшікті лыптамасын шешеді. |
top(num, lines) | TOP num lines | Команда RETR-ге сас, біра тек таырыпшаны жне хабарлама денесіні lines жолын жктейді. Кортежді (resp, lst, octets) айтарады. |
uidl([num]) | UIDL [num] | "unique-id listing"-тан ысартылан (хабралама индификаторларыны бірегей тізімі). Нтиже форматы: (resp, lst, octets), егер num крсетілмесе, жне "+OK num uniqid", егер крсетілсе. Lst тізімі "+OK num uniqid" тріндегі жолдардан трады. |
Бл кестеде num хабарлама нмерін білдіреді (ол барлы сессия аралыында згертілмейді), resp – сервер жауабы, кез келген команда шін айтарылады, нтижелі операциялар шін “+OK”-тан басталады (стсіздік кезінде poplib.proto_error ерекше жадайы туындайды). Octets параметрі абылданан мліметтерді байттар санын білдіреді. uniqid – сервермен жинаталан хабарлама идентификаторы.
POP3-сервермен жмыс ш кезенен трады: идентификация, транзакция жне жаарту. Идентификация кезеінде, POP3-объектсін раннан кейін бірден, тек USER, PASS (иногда APOP и RPOP) командалары рсат етілген. Идентификациядан кейін сервер олданушы жайлы мліметті алады жне транзакция кезеі басталады. Бнда алан командалар орналастырылан. Жаарту кезеі QUIT командасымен шаырылады, солан кейінгі POP3-сервер берілген командалармен олданушыны почталы жшігін жаартады, яни хабарламаны шіру шін белгіленгендерді шіреді.