計算機網(wǎng)絡(luò)-套接字編程作業(yè)(3)-郵件客戶端

背景知識

1)梳理邏輯(摘自SMTP的連接和發(fā)送過程):
(a)建立TCP連接(使用Socket)
(b)客戶端發(fā)送HELO/EHLO命令以標識發(fā)件人自己的身份, 接受 服務(wù)器端響應(yīng);
(c)客戶端發(fā)送AUTH LOGIN登錄請求,接著發(fā)送用戶名和密碼;
(d)客戶端發(fā)送RCPT命令,以標識該電子郵件的計劃接收人,可以有多個RCPT行;
(e)協(xié)商結(jié)束,發(fā)送郵件,用命令DATA發(fā)送
(f)以.表示結(jié)束輸入內(nèi)容一起發(fā)送出去
(g)結(jié)束此次發(fā)送,用QUIT命令退出

2)每個命令都以\r\n結(jié)尾,特定格式命令:
HELO:HELO <domain> <CRLF>
RCPT TO:<forward-path> <CRLF>——<forward-path>
3)選擇郵箱服務(wù)器
gmail還要翻墻,棄用(? 。?)
我是使用網(wǎng)易郵箱作為郵箱服務(wù)器,公司郵箱作為目標賬戶。
網(wǎng)易郵箱需要提前進行一些設(shè)置,開啟STMP功能,方法如下:

  1. 登錄郵箱 -- 設(shè)置 -- 進入POP3/SMTP/IMAP界面,可以看最下面提示有SMTP服務(wù)器: smtp.163.com
  2. 勾選 IMAP/SMTP服務(wù),會彈出提示設(shè)置授權(quán)碼
  3. 進入設(shè)置授權(quán)碼,開啟服務(wù),這里需要手機號碼驗證(如果你和我一樣,關(guān)聯(lián)的手機號碼已經(jīng)不知道丟哪里了,可以換一個綁定當前手機的網(wǎng)易郵箱,(^ ^)),總之,設(shè)置好授權(quán)碼后,這個授權(quán)碼就是代碼里的password

下面是最終代碼展示:

from socket import *
import base64
msg = 'I love computer networks!'
endmsg = '\r\n.\r\n'
# 郵件服務(wù)器,端口 25 
mailserver = 'smtp.163.com'

fromaddr = 'z****@163.com' # 填寫自己的郵箱
toaddr = 'z***@***.com' # 填寫目標郵箱
username = 'z****@163.com'
password = 'a*****6' # 網(wǎng)易郵箱授權(quán)碼

# Create socket called clientSocket and establish a TCP connection with mailserver
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((mailserver, 25))
recv = clientSocket.recv(1024).decode()
print(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.encode())
recv1 = clientSocket.recv(1024).decode()
print(recv1)
if recv1[:3] != '250':
    print('250 reply not received from server.')

# send AUTH LOGIN command
base64_str = ('\x00' + username + '\x00' + password).encode()
base64_str = base64.b64encode(base64_str)
authCommand = 'AUTH PLAIN '.encode() + base64_str + '\r\n'.encode()
clientSocket.send(authCommand)
recv_auth = clientSocket.recv(1024)
print(recv_auth.decode())

# Send MAIL FROM command and print server response.
mailCommand = 'MAIL FROM: <' + fromaddr + '>\r\n'
clientSocket.send(mailCommand.encode())
recv_from = clientSocket.recv(1024).decode()
print(recv_from)
if recv_from[:3] != '250':
    print('250 reply not received from server.')

# Send RCPT TO command and print server response.
rcptCommand = 'RCPT TO: <' + toaddr + '>\r\n'
clientSocket.send(rcptCommand.encode())
recv_rcpt = clientSocket.recv(1024).decode()
print(recv_rcpt)
if recv_rcpt[:3] != '250':
    print('250 reply not received from server.')

# Send DATA command and print server response.
clientSocket.send('DATA\r\n'.encode())
recv_data = clientSocket.recv(1024).decode()
print(recv_data)
if (recv_data[:3] != '354'):
    print('354 reply not received from server')

# Send message data.
send_msg = 'from: ' + fromaddr + '\r\n'
send_msg += 'to: ' + toaddr + '\r\n'
send_msg += 'subject: ' + msg + '\r\n'
send_msg += 'content-type: text/plain\t\n'
send_msg += '\r\n' + msg
clientSocket.send(send_msg.encode())

# Message ends with a single period.
clientSocket.send(endmsg.encode())
recv = clientSocket.recv(1024).decode()
print(recv)
if (recv[:3] != '250'):
    print('250 reply not received from server')

# Send QUIT command and get server response.
clientSocket.send('QUIT\r\n'.encode())

# close
clientSocket.close()

結(jié)果:


bb.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容