星期五, 7月 10, 2009

SMTP in Python - 1

要寄信很簡單,只要先import smtplib即可。


import smtplib
s = smtplib.SMTP(server)
s.sendmail(fromaddr, toaddrs, message)


server:寄信的伺服器
fromaddr:寄件人
toaddrs:收件人(可以是list)
message:信件內容

再來看看關於SMTP的protocol conversation
平時smtpobj預設是關閉debug的,因此要另外打開。


try:
s = smtplib.SMTP(server)
s.set_debuglevel(1)
s.sendmail(frmaddr, toaddr, message)
except (socket.gaierror, socket.error, socket.herror, smtplib.SMTPException), e:
print " *** Your message may have not been sent!"
print e
sys.exit(1)
print "Message successfully sent to %d recipient(s)" % (len(toaddr))


多加了s.set_debuglevel(1)執行此程式就會顯示SMTP conversation messages

整支程式跑起來如下:

cacaegg@cacabook:~/workspace/NetworkProgram/src/SMTP$ debug.py localhost cacaegg@localhost cacaegg@localhost
send: 'ehlo [127.0.1.1]\r\n'
reply: '250-cacabook Hello localhost [127.0.0.1], pleased to meet you\r\n'
reply: '250-ENHANCEDSTATUSCODES\r\n'
reply: '250-PIPELINING\r\n'
reply: '250-EXPN\r\n'
reply: '250-VERB\r\n'
reply: '250-8BITMIME\r\n'
reply: '250-SIZE\r\n'
reply: '250-DSN\r\n'
reply: '250-ETRN\r\n'
reply: '250-AUTH DIGEST-MD5 CRAM-MD5\r\n'
reply: '250-DELIVERBY\r\n'
reply: '250 HELP\r\n'
reply: retcode (250); Msg: cacabook Hello localhost [127.0.0.1], pleased to meet you
ENHANCEDSTATUSCODES
PIPELINING
EXPN
VERB
8BITMIME
SIZE
DSN
ETRN
AUTH DIGEST-MD5 CRAM-MD5
DELIVERBY
HELP
send: 'mail FROM: size=155\r\n'
reply: '250 2.1.0 ... Sender ok\r\n'
reply: retcode (250); Msg: 2.1.0 ... Sender ok
send: 'rcpt TO:\r\n'
reply: '250 2.1.5 ... Recipient ok\r\n'
reply: retcode (250); Msg: 2.1.5 ... Recipient ok
send: 'data\r\n'
reply: '354 Enter mail, end with "." on a line by itself\r\n'
reply: retcode (354); Msg: Enter mail, end with "." on a line by itself
data: (354, 'Enter mail, end with "." on a line by itself')
send: 'To: cacaegg@localhost\r\nFrom: cacaegg@localhost\r\nSubject: Test Message from simple.py\r\n\r\nHello,\r\n\r\nThis is a test message sent to you fromsimple.py and smtplib.\r\n.\r\n'
reply: '250 2.0.0 n6A2nMKj013583 Message accepted for delivery\r\n'
reply: retcode (250); Msg: 2.0.0 n6A2nMKj013583 Message accepted for delivery
data: (250, '2.0.0 n6A2nMKj013583 Message accepted for delivery')
Message successfully sent to 1 recipient(s)


最後簡單註解模擬一下SMTP conversation protocol ([]為註解)

send: 'ehlo [127.0.1.1]\r\n'
[client:server 你好,我是127.0.1.1]

reply: '250-ENHANCEDSTATUSCODES\r\n'
...bala
reply: '250 HELP\r\n'
reply: retcode (250); Msg: cacabook Hello localhost [127.0.0.1], pleased to meet you
[server: cacabook 你好,我有這些提供這些服務的選項,來參考看看]

ENHANCEDSTATUSCODES
...bala
HELP
[client murmur:那我就選這些 bala...]

send: 'mail FROM: size=155\r\n'
[client: 這封信是從cacaegg@localhost來的,大小是155 byte]

reply: '250 2.1.0 ... Sender ok\r\n'
reply: retcode (250); Msg: 2.1.0 ... Sender ok
[server: 寄件人... 好的]

send: 'rcpt TO:\r\n'
[client: 我要寄給cacaegg@localhost]

reply: '250 2.1.5 ... Recipient ok\r\n'
reply: retcode (250); Msg: 2.1.5 ... Recipient ok
[server: 收件人... 好的]

send: 'data\r\n'
[client: 我要開始說信件內容囉]

reply: '354 Enter mail, end with "." on a line by itself\r\n'
reply: retcode (354); Msg: Enter mail, end with "." on a line by itself
[server: 請說!說完以後就在打上.我就知道你說完了!]

data: (354, 'Enter mail, end with "." on a line by itself')
send: 'To: cacaegg@localhost\r\nFrom: cacaegg@localhost\r\nSubject: Test Message from simple.py\r\n\r\nHello,\r\n\r\nThis is a test message sent to you fromsimple.py and smtplib.\r\n.\r\n'
[client: 我的內容是balabala....]
[client: .]

reply: '250 2.0.0 n6A2nMKj013583 Message accepted for delivery\r\n'
reply: retcode (250); Msg: 2.0.0 n6A2nMKj013583 Message accepted for delivery
[server: 好的,我會幫你寄送!]

其實server說好也不一定代表信就會寄出,可能原因有很多種,舉些例子
1.server判斷你是spam,就不幫你寄信了
2.server只是轉寄站,還要繼續轉寄到其他的mail server,可能到最後還是無法到達。
這情況通常會有bounce message

附件:為整支程式,可以抓下來直接跑!

沒有留言: