文章出處
文章列表
發送郵件可以用smtp協議,整個過程為:
用戶代理(user-agent,比如outlook、foxmail等郵件客戶端)---(smtp協議)--->本地郵件服務器 --- (smtp協議)---> 遠程郵件服務器 --- (imap,pop3或http協議)--->遠程客戶代理(收取郵件)
其中本地郵件服務器和遠程郵件服務器是直通式,一般不經過中轉,如果遠程郵件服務器沒開啟等原因導致發送失敗那么過一段時間后重復發送。這是本地郵件服務器的職責。
smtp是應用層協議,下面需要tcp協議支撐。smtp報文作為tcp報文的數據部分進行傳輸。因此我們自行創建TCP socket,并將smtp報文作為數據,塞到tcp socket中進行發送。
smtp報文的構造,根據協議,包括MAIL FROM, RCPT TO, DATA, . ,QUIT等部分。構造起來不復雜。
最后一個子問題是獲取郵件服務器的地址。通過nslookup -qt=mx xxx.com來獲取,比如nslookup -qt=mx 163.com得到163mx02.mxmail.netease.com,端口一般是25。
那么接下來就是code
#coding:utf-8
from socket import *
msg = "\r\n I love computer networks!" #需要發送的數據
endmsg = "\r\n.\r\n"
# Choose a mail server (e.g. Google mail server) and call it mailserver
mailserver = ("163mx02.mxmail.netease.com",25) #Fill in start #Fill in end
# Create socket called clientSocket and establish a TCP connection with mailserver
#Fill in start
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect(mailserver)
#Fill in end
recv = clientSocket.recv(1024)
print 'recv:',recv
if recv[:3] != '220':
print '220 reply not received from server.'
# Send HELO command and print server response.
heloCommand = 'HELO Alice\r\n'
clientSocket.send(heloCommand)
recv1 = clientSocket.recv(1024)
print 'recv1:',recv1
if recv1[:3] != '250':
print '250 reply not received from server.'
# Send MAIL FROM command and print server response.
# Fill in start
fromCommand = "MAIL FROM:<system@net.cn>\r\n" #匿名郵件的「發送人」,可以隨意偽造
clientSocket.send(fromCommand)
recv2 = clientSocket.recv(1024)
print 'recv2:', recv2
# Fill in end
# Send RCPT TO command and print server response.
# Fill in start
toCommand = "RCPT TO:<superman@163.com>\r\n" #收件人地址。
clientSocket.send(toCommand)
recv3 = clientSocket.recv(1024)
print 'recv3:', recv3
# Fill in end
# Send DATA command and print server response.
# Fill in start
dataCommand = "DATA\r\n"
clientSocket.send(dataCommand)
recv4 = clientSocket.recv(1024)
print 'recv4:', recv4
# Fill in end
# Send message data.
# Fill in start
clientSocket.send(msg)
# Fill in end
# Message ends with a single period.
# Fill in start
clientSocket.send(endmsg)
# Fill in end
# Send QUIT command and get server response.
# Fill in start
quitCommand = "QUIT\r\n"
clientSocket.send(quitCommand)
recv5 = clientSocket.recv(1024)
print 'recv5:', recv5
# Fill in end
clientSocket.close()
注意如果郵件找不到,可能歸類到垃圾郵件了。一個解決辦法是把郵件內容數據(msg)加密后再發送。
ref:《計算機網絡:自頂向下方法》第6版 第二章 套接字編程作業3 郵件客戶
文章列表
全站熱搜