《计算机网络自顶向下方法》第二章套接字编程作业——邮件客户端

目录

一、实验内容

 二、实验过程

 三、实验结果

 四、附加实验


一、实验内容

    通过完成本实验,您将更加了解SMTP协议。您还将学到使用Python实现标准协议的经验。

    您的任务是开发一个简单的邮件客户端,将邮件发送给任意收件人。您的客户端将需要连接到邮件服务器,使用SMTP协议与邮件服务器进行对话,并向邮件服务器发送电子邮件。 Python提供了一个名为smtplib的模块,它内置了使用SMTP协议发送邮件的方法。但是我们不会在本实验中使用此模块,因为它隐藏了SMTP和套接字编程的细节。

    为了限制垃圾邮件,一些邮件服务器不接受来源随意的TCP连接。对于下面所述的实验,您可能需要尝试连接到您的大学邮件服务器和流行的Webmail服务器(如AOL邮件服务器)。您也可以尝试从您的家和您的大学校园进行连接。

    下面你会找到客户端的代码框架。您将完成代码框架。您需要填写代码的地方标有#Fill in start和#Fill in end。每个地方都可能需要不止一行代码。在某些情况下,接收邮件服务器可能会将您的电子邮件分类为垃圾邮件。当您查找从客户端发送的电子邮件时,请检查垃圾邮件文件夹。

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 = #Fill in start   #Fill in end
# Create socket called clientSocket and establish a TCP connection with mailserver
#Fill in start

#Fill in end
recv = clientSocket.recv(1024)
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)
recv1 = clientSocket.recv(1024)
print recv1
if recv1[:3] != '250':
    print '250 reply not received from server.'

# Send MAIL FROM command and print server response.
# Fill in start

# Fill in end

# Send RCPT TO command and print server response.
# Fill in start

# Fill in end

# Send DATA command and print server response.
# Fill in start

# Fill in end

# Send message data.
# Fill in start

# Fill in end 

# Message ends with a single period.
# Fill in start

# Fill in end

# Send QUIT command and get server response.
# Fill in start

# Fill in end
 

 二、实验过程

实验完整代码如下:

from socket import *
import base64

# 选择一个邮箱服务器,这里我们选择网易邮箱的服务器为"smtp.163.com"
mailserver = "smtp.163.com"
mailUser = '***'   # 填入你邮箱的用户名
mailFromAddress = '15****468@163.com'  # 填入你发送邮箱的账号
mailPassWord = 'ZUT*****AKX'   # 填入你的验证码,而不是你的密码,具体原因见下
mailToAddress = '25****54@qq.com'  # 填入你接受邮箱的账号


# 这段代码是用于构建一个简单的邮件消息。其中,msg包含了
# 邮件的头部信息,例如发件人、收件人和主题,以及邮件正文。
# endmsg是邮件的结尾标志。Subject代表邮件的主体,FROM为发件人,TO为收件人
msg = 'FROM: ' + mailFromAddress + '\r\n'
msg += 'TO: ' + mailToAddress +  '\r\n'
msg += 'Subject: ' + 'text' +  '\r\n'
msg += "\r\n I love computer net"
endmsg = "\r\n.\r\n"

# 建立与服务端的TCP连接,可以查到网易邮箱的端口号为25,qq邮箱的为465
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((mailserver, 25))

recv = clientSocket.recv(1024)
recv = recv.decode()
print(recv)
if recv[:3] != '220':
    print('220 reply not received from server.')

# HELO命令通常用于与SMTP服务器建立初始连接并声明自己的身份。
# 它包含的参数通常是发送方主机的名称或IP地址。
heloCommand = 'HELO mailserver\r\n'
while True:
    clientSocket.send(heloCommand.encode())
    recv = clientSocket.recv(1024)
    recv = recv.decode()
    print(recv)
    if recv[:3] == '250':  # 这里表明如果接收到的服务器发送的报文前三个字符为‘250’,则表明发送成功
        break

# 登录命令
loginCommand = 'auth login\r\n'
while True:
    clientSocket.send(loginCommand.encode())
    recv = clientSocket.recv(1024)
    recv = recv.decode()
    print(recv)
    if recv[:3] == '334':
        break

# 邮箱账户经过base64编码
userCommand = base64.b64encode(mailUser.encode()) + b'\r\n'
while True:
    clientSocket.send(userCommand)
    recv = clientSocket.recv(1024)
    recv = recv.decode()
    print(recv)
    if recv[:3] == '334':
        break

# 邮箱密码经过base64编码 这里不展示密码了
passCommand = base64.b64encode(mailPassWord.encode()) + b'\r\n'
while True:
    clientSocket.send(passCommand)
    recv = clientSocket.recv(1024)
    recv = recv.decode()
    print(recv)
    if recv[:3] == '235':
        break

# Send MAIL FROM command and print server response.
MFCommand = 'MAIL FROM: <'+ mailFromAddress + '>\r\n'
while True:
    clientSocket.send(MFCommand.encode())
    recv = clientSocket.recv(1024)
    recv = recv.decode()
    print(recv)
    if recv[:3] == '250':
        break

# Send RCPT TO command and print server response.
RTCommand = 'RCPT TO: <'+ mailToAddress + '>\r\n'
while True:
    clientSocket.send(RTCommand.encode())
    recv = clientSocket.recv(1024)
    recv = recv.decode()
    print(recv)
    if recv[:3] == '250':
        break

# Send DATA command and print server response.
DATACommand = 'DATA\r\n'
while True:
    clientSocket.send(DATACommand.encode())
    recv = clientSocket.recv(1024)
    recv = recv.decode()
    print(recv)
    if recv[:3] == '354':
        break

# Send message data.
clientSocket.send(msg.encode())

# Message ends with a single period.
while True:
    clientSocket.send(endmsg.encode())
    recv = clientSocket.recv(1024)
    recv = recv.decode()
    print(recv)
    if recv[:3] == '250':
        break

# Send QUIT command and get server response.
QUITCommand = 'QUIT\r\n'
while True:
    clientSocket.send(QUITCommand.encode())
    recv = clientSocket.recv(1024)
    recv = recv.decode()
    print(recv)
    if recv[:3] == '221':
        break

由于现在的邮箱都有保护机制,禁止第三方脚本进行发送邮件任务,所以我们必须先对发送方邮箱进行一下设置。首先找到设置界面,找到如图所示。然后开启服务,最后邮箱会给你一个验证码用于第三方登录,所以上面填写邮箱密码的地方要填入这里给出的验证码。设置完成后,就能进行发送邮件啦。

 三、实验结果

代码运行结果如下,同时你也要注意你的邮箱是否收到邮件,如果没受到,请记得检查一下垃圾邮箱。

 四、附加实验

其实,如果用python发送邮件其实不必这么麻烦,只不过我们需要了解邮件发送的内部逻辑是什么。通常情况下,我们只需要使用smtplib包即可,若邮件发送成功,则会打印邮件发送成功。注:别忘了qq邮箱也同样要进行设置才能用第三方脚本发送邮件。

代码展示如下:

import smtplib
from email.mime.text import MIMEText
from email.header import Header

# 创建发送邮件的一系列相关对象
from_addr='11****13@qq.com'
password='qq******cih'

to_addr='15****468@163.com'
smtpserver='smtp.qq.com'

# 利用上面的MIMEText以及Header来帮助我们构建一个简单的邮件消息
msg=MIMEText('使用python测试发送邮件','plain','utf-8')

msg['From']=Header('119****13@qq.com')
msg['To']=Header('15****68@163.com')
subject='python SMTP 邮件测试'

msg['Subject']=Header(subject,'utf-8')

try:
    # 这段代码创建了一个基于 SSL 的 SMTP 连接对象。相对于普通的 SMTP 连接,
    # 基于 SSL 的 SMTP 连接会对通信内容进行加密,提高了邮件的安全性。
    # SSL不支持25号端口,所以这里改成了465号端口,因此我们要用qq邮箱来发送
    smtpwork=smtplib.SMTP_SSL(smtpserver)
    smtpwork.connect(smtpserver,465)

    smtpwork.login(from_addr,password)
    smtpwork.sendmail(from_addr,to_addr,msg.as_string())
    print("邮件发送成功")

except smtplib.SMTPException:
    print("邮件发送失败")

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值