1、毕业设计(论 文) 题 目 基于SOCKET协议的SMTP 邮件发送网关的设计开发 专 业 电子信息科学与技术 班 级 电技 081 学 生 胡 爱 军 指导教师 侯 浩 录 2012 年西安理工大学本科生毕业设计(论文)基于SOCKET协议的SMTP邮件发送网关的设计开发专业:电子信息科学与技术班级:电技081班作者:指导教师: 职称:讲 师答辩日期:2012-06-24 摘 要本次毕业设计的课题要求是从SMTP协议的套接字底层开始,完成客户端与SMTP服务器的交互过程,最终完成邮件发送。在本文中,我使用了delphi7.0的编程语言环境,利用seversocket和clientsocket
2、控件完成客户端与虚拟服务器之间的连接和发送消息。着重分析了系统的功能需求,包括了连接邮箱服务器模块、与服务器完成交互模块、邮件体定义发送模块。详细论述了利用clientsocket组件完成与邮箱服务器的交互,在交互中通过BASE64加密认证了用户和密码;按照RFC822协议和MIME的扩展定义了邮件体,采用了发件箱、收件箱、主题和时间四个邮件头,并与邮件正文统一的赋给了一个字符串,最后成功的完成了邮件发送,达到了设计的要求。关键词:套接字、简单邮件传输协议、交互、BASE64加密、邮件体AbstractThe points of the task in the graduation desig
3、n are as follows, starting from the bottom socket of the SMTP, to complete the interaction processing of the client and the SMTP server, and finally accomplish e-mail sending.In this article, delphi7.0 development environment is utilized. Two components, seversocket and clientsocket are used to comp
4、lete the connection and message sending between virtual server and client. The functional requirements of the system are analyzed, including mailbox server connection module, server interaction accomplishment module, and the definition and sending module of the message body. The method of mailbox se
5、rver interaction is expounded in detail by the use of clientsocket. At the same time, BASE64 is applied to encode user-name and password; message body is defined based on the RFC822 and the extension of MIME. Four e-mail headers, outbox, inbox, subject and time are used, together with the unified bo
6、dy of the message form a string, then successfully completed e-mail sending.Keywords: socket, SMTP, interaction, BASE64, e-mail body目 录1 绪 论11.1 课题研究背景及意义11.1.1 电子邮件的发展历程和课题提出背景11.1.2 课题研究的意义31.2 delphi7.0开发环境简介42 系统设计目标及需求分析62.1 系统设计的目的及任务62.2 系统的流程图62.3 系统的需求分析72.3.1 连接服务器模块82.3.2 与邮件服务器交互模块82.3.3
7、 邮件体定义和发送定义模块93 SOCKET103.1 套接字的使用103.2 clientsocket和seversocket控件123.3利用SOCKET完成消息传送133.4 基于SOCKET协议下SMTP邮件发送过程154 程序实现184.1 交互实现184.1.1 从连接服务器到AUTH LOGIN194.1.2 BASE64加密认证用户及密码214.1.3 MAIL FROM 到DATA234.2 邮件体的定义和发送244.2.1 邮件格式的定义254.2.2邮件的发送294.3 系统界面的完善和自我评价314.3.1系统的完善314.3.2 自我评价32致 谢34参考文献35附
8、录36附录一 SMTP命令和响应36附录二 BASE64索引表37附录三 主要核心程序代码38I1 绪 论1.1 课题研究背景及意义1.1.1 电子邮件的发展历程和课题提出背景 电子邮件的诞生是在1971年秋季(确切的时间已经无法考证),当时已经有一种可传输文件的电脑程序以及一种原始的信息程序。但两个程序存在极大的使用局限例如:使用信息程序的人只能给接收方发送公报,接收方的电脑还必须与发送方一致。 发明电子邮件时,汤姆林森是马萨诸塞州剑桥的博尔特.贝拉尼克.纽曼研究公司(BBN)公司的重要工程师,当时,这家企业受聘于美国军方,参与Arpanet网络(互联网的前身)的建设和维护工作。汤姆林森对已
9、有的传输文件程序以及信息程序进行研究,研制出一套新程序,它可通过电脑网络发送和接收信息,再也没有了以前的种种限制。为了让人们都拥有易识别的电子邮箱地址,汤姆林森决定采用符号,符号前面加用户名,后面加用户邮箱所在的地址。电子邮件由此诞生。虽然电子邮件是在70年代发明的,它却是在80年才得以兴起。70年代受网络速度的限制,那时的用户只能发送些简短的信息;到80年代中期,个人电脑兴起,电子邮件开始在电脑迷以及大学生中广泛传播开来;到90年代中期,互联网浏览器诞生,全球网民人数激增,电子邮件被广为使用。随着我国和世界的经济的迅速地发展,网络的应用普及到了各种大小型企业甚至个人生活.所以当办公应用的砝码
10、不断被加入互联网,注定了天平会向电子邮箱这端倾斜的不争事实。而我国目前的邮件发展趋势分为:趋势一,邮件处理程序的改变电子邮件给我们工作带来便捷的同时,也会在不经意间打扰我们的工作。很多朋友或网友会抱怨占用我们的时间、打扰工作和学习的思路等。但是事实上,如果我们每天定时处理邮件,可能每天两次或者四次,总之依据自己的邮件往来数量制定好适合自己的工作习惯,让邮件处理的程序随你而改变。趋势二,电子邮箱的灵活和方便当电子邮箱变的不再新鲜,未来潮流将如何?从网易免费邮箱的网络硬盘,到公开注册的F的4G文件中转站;从新浪企业推出奇G邮箱,到263推出“无限容量”的263G邮箱后,更加坚定了存储容量在用户市场
11、中的地位。借着网速的不断提升和未来光纤的普及,这又将会是在线存储的又一个春天。但万物复苏的春天是短暂的,未来的电子邮箱,绝不会在停留在邮箱存储上,也不再只是一个简单的信息交换、存储应用,而是朝着更灵活、方便的方向发展。趋势三,桌面办公的普及邮件桌面客户端是未来发展核心应用之三。电子邮箱未来的发展,更多的应用扩展和体验,象DreamMail、FoxMail、Outlook等这类的桌面客户端将无疑扮演着最重要的角色。电子邮箱客户端将使人们脱离频繁登陆Web页面的烦恼。凭借着飞快的网速,在上传附件方面将与Web页面的速度一样,甚至更快速。趋势四,移动办公的成熟客户端结合移动邮箱服务将是未来发展核心应
12、用之四。移动邮箱在具备常规互联网邮件功能的同时,充分利用手机的功能优势,让用户可以通过手机短信、彩信或手机WAP上网方式,随时随地获取邮件信息、对邮件进行操作,实现真正的移动畅快沟通。只要手机有信号,不用在乎有没有带宽接入,随时随地都可以查收邮件。当前往3G时代的路上,移动邮箱的成熟定会成为历史,会有越来越多的用户在享受传统邮箱的互联网邮件功能同时,加入体验移动邮箱的短信、彩信、邮件到达通知等移动特色服务的行列。趋势五,邮件安全化的日益加强随着网络的发展,电子邮件的应用也用在了越来越多的地方,据此原因电子邮件服务对安全提出了越来越多的要求! 而传统电子邮件技术是一种安全性较差的信息传输技术,目
13、前,因特网用户所使用的绝大多数电子邮件系统中,基本没有采取任何措施来保证电子邮件在网络中安全传送。电子邮件的内容以明文的形式在网络中传递,使其面临着被截获、篡改、破坏的危险;甚至导致不法人员利用邮件进行欺骗等不良行为。电子邮件系统存在的这些问题,制约了它在政府办公、银行、保险、海关、税务、公安系统等一些涉密部门的进一步使用。另外,全球范围内普遍存在并不断激化的病毒邮件和垃圾邮件问题,也正不断制约着电子邮件市场的发展。邮件安全、防病毒、反垃圾已经成为邮件服务提供商、广大个人和企业用户,甚至整个社会共同关注和关心的焦点。有鉴于此,国内外电子邮件系统相关各方都进行了大量的工作,包括在电子邮件系统中引
14、入数字证书,建立各种加密邮件协议和标准,研究邮件防病毒技术和垃圾邮件过滤技术等;同时,不少国家都出台了电子邮件应用相关的法律法规,如电子签名法、反垃圾邮件法等,对其进行约束和规范。安全电子邮件系统涉及相当宽泛的技术领域,包括CA认证技术、密码技术、Web技术、数据库技术、防病毒技术、反垃圾邮件技术等。1.1.2 课题研究的意义本课题的提出是处于在全球网络环境日益发展电子邮件发送应用在生活、学习、工作以及各个方面下的背景中。而在电子邮件的应用中,安全又是一个特别重要的发展趋势也是应用者们所需要的!本课题是要从SOCKET的套接字底层分析开始,逐渐的根据SMTP(简单邮件传输协议)协议与服务器交互
15、,完成每一步服务器提出的要求,最后完成邮件发送,使得邮件传输是个很安全过程。本课题的从套接字底层做起,加强了邮件发送的安全性,能够有效地避免邮件在传输中的信息丢失或者被他人盗取、使用、知晓、修改等可能;同时由于在使用indy控件时,太多的服务器将其当做垃圾邮件处理或是限定发邮件的数量,从而使得用户在信息联络上受到损失。1.2 delphi7.0开发环境简介Delphi是美国Borland公司开发的一种全新的可视化软件开发工具。它采用了面向对象程序语言和基于组件的开发结构框架相结合的先进技术。Delphi这种先进的编程理念和强大的可视化编程功能,克服了其他的面向对象语言在与用户交互能力上的不足。
16、同时,它强大和先进的数据库处理技术和能快速地建立应用程序的独特优势,为程序开发人员在开发应用程序上提供了便利。这使得原本繁琐复杂而又枯燥的编程工作在Delphi的帮助下变的简单易学而又有趣。而值得一提的是它的delphi7.0版本,在保持原有版本优点的基础上增加了更新更强的新特性:扩大了VCL可视化组件库;对编辑器和编译器方面做了更多改进和优化;增加了多种网络应用开发的空间包括indy和Web编程技术;完全支持.NET技术;支持跨平台开发类库CLX。Delphi作为Borland公司的巅峰之作,它是有着鲜明的特点的:(1)简化程序执行过程,编译速度快。Delphi所使用的全特征代码编辑器和高速
17、度的编译器使其直接生成高性能代码,从而加快了编译速度。(2)可在多个不同的平台上开发应用。Delphi7可以在各种Windwos环境下使用,同时也可以在Linux平台上开发应用。(3)具有更好的可重用性、可管理性和可扩展性。Delphi7.0使用的是ObjectPascal面向对象编程语言并提供了许多程序框架和可重复利用的可视化组件。另外,Delphi7使用了独特的VCL(Visual Component Library)类库。VCL即可视组件库,它可扩展性强、操作简单、封装完整。用户可以根据自己的需要,可以任意导入导出ActiveX控件也可以任意构建、扩充、甚至是删减VCL。这大大提高了程序
18、开发效率。同时,开发人员还可以根据自己的意愿来控制Windows开发效果。(4)具有强大的数据可处理能力。应用程序通过Delphi7可以使用Borland公司提供的数据处理工具BDE(Borland Database Engine),这样应用程序就能可以方便的使用BDE连接到的各种格式的数据源。并能畅通的使用Oracle、Sybase、SQL Server等多种大型数据库。在老师的推荐下,也因为delphi编程语言的强大的所在,所以我选择了在本次毕业设计中使用delphi7.0语言。2 系统设计目标及需求分析2.1 系统设计的目的及任务本次毕设课题:基于SOCKET协议的SMTP邮件发送网关的
19、设计开发。要求从SMTP的套接字底层交互开始,完成交互的各个步骤,直到最后能够成功的向SMTP服务器发送出邮件。课题的具体内容:(1)学习邮件网关的实现思路并研究该模型的实现方案,提出合理的用户需求设计;(2)学习DELPHI编程工具并掌握数据库的简单使用(3)了解网络通讯的基本原理和数据编码基本概念,完成SOCKET协议字的套接过程,实现邮件数据的标准编码以及邮件客户端向邮件服务器发送邮件信息的要求。课题主要的重点和难点在于:SMTP协议要理解透彻,懂得用户与服务器交互的每一个具体过程;delphi7.0语言的使用和其网络组件的特性和使用,能够懂得SOCKET协议的套接字底层的使用方法;最后
20、的关键是邮件体的各种编码和加密,掌握邮件消息的编码方法以及邮件主题、发件人、收件人、发件人名称、收件人名称、邮件主题内容等内容节的具体编码要求和实现方法;编程实现按照用户的基本设定实现邮件消息的完整编码、实现远端邮件服务器的登陆认证,实现与远端邮件服务器的网络通讯;并最终完成邮件发送。2.2 系统的流程图本次毕设课题是从连接SMTP服务器开始的,终结于邮件发送,下面图2-1是我的系统设计的流程图:图 2-1 系统设计流程图2.3 系统的需求分析本次毕设的课题的基本要求是:分析目前网络通讯中最常使用的的邮件发送协议SMTP协议,从该协议的套接字底层开始分析,用SOCKET协议完整的实行SMTP协
21、议的解析和执行,完成向远端服务器发送邮件的完整过程。由于是从套接字底层开始的,所以在系统的操作中,我们需要操作SMTP协议中交互的每一步。在我的邮件发送系统功能模块中分为三个主要的功能:连接邮箱服务器模块、与服务器完成交互模块、邮件体定义和发送模块。图2-2是我的系统功能模块的示意图:邮件发送连接服务器交互过程邮件体的设置连接服务器监视连接状态断开连接普通交互Base64加密验证用户Base64加密验证密码发件箱收件箱Base64加密主题Base64加密正文图2-2 邮件发送的功能模块2.3.1 连接服务器模块在这个模块,主要通过控制clientsocket的Active属性是false还是t
22、rue来连接服务器,并显示连接是否成功或者断开连接是否成功。2.3.2 与邮件服务器交互模块这块比较多,普通的一般的交互是直接向服务器发出请求,例如常用的:HELO、EHLO、AUTH LOGIN、DATA、NOOP等。但是还有两个不是直接的普通交互,就是服务器在验证用户账号和用户密码时,需要先经过base64加密。而且由于与邮箱服务器的交互每一次只能发送一个包也就是一步一步的交互,所以这个模块的按钮比较多。2.3.3 邮件体定义和发送定义模块一个完整的邮件包括邮件头和正文两个部分。而邮件头又包含着不同的头段,在我的设计里运用了主题、发件箱、收件箱和发件时间这四个头段组成一个完整的邮件头。其中
23、除了时间是利用delphi中的date或now函数直接提取本地主机时间之外其余都需要由可视化常用组件手动输入。所以在这个模块里,邮件体的内容设置是几乎完全可以看见的。而这些输入的内容也完整地组成了一个标准的邮件体。关于邮件体的定义和发送将在后面的4.2章节中详细介绍。3 SOCKET3.1 套接字的使用SOCKET是建立在传输协议上的一个套接字规范,它定义了两台计算机间进行通信的规范。SOCKET实质上提供了进程通信的端点。进程通信之前,双方首先必须各自创建一个端点,否则是没有办法建立联系并相互通信的,套接字也就相当于是两台机器间通信“通道”的两端。在使用套接字进行网络通信之前,必须设置套接字
24、的属性,套接字内部数据结构必须包含正确的地址。套接字数据结构必须包含本地主机和远程主机正确的协议端口和IP地址。Delphi7.0 提供你写网络服务器或客户应用程序去读和写其他的系统。一个服务或客户程序通常专注于一个单一的服务如超文本传送协议(HTTP)或文件传输协议(FTP)。使用seversocket,一个应用程序可以提供这些服务中的一个去连接一个希望使用服务的客户程序。而clientsocket允许一个应用使用这些服务中的一个去连接提供这个服务的服务应用。Socket连接可以分成三个基本的类型,它们反映了如何开始连接和本地Socket 连接是什么。这三个类型是:1.客户端连接 客户端连接
25、是一个客户端SOCKET与一个远程系统上的服务端SOCKET连接。客户端连接由客户端SOCKET开始。首先,客户端SOCKET必须描述它想连接到的服务端SOCKET. 接着客户端SOCKET查找服务端SOCKET,当找到服务器时,就请求连接。服务器SOCKET维持一个客户端请求队列,在他们有时间时完成连接。当服务端SOCKET接受客户端连接,服务端SOCKET将向它想连接的客户SOCKET发送一个完整的描述,客户端的连接完成。2.倾听连接服务器 SOCKET不会去定位客户端,而是他们形成被动的半连接状态,倾听来自客户端的请求。服务器SOCKET形成一个队列,存放它们听到的连接请求。当服务器SO
26、CKET同意客户连接请求时,它形成一个新的SOCKET去连接客户端,因此这个倾听连接能保持开放状态允许其他客户端请求。3.服务端连接当倾听SOCKET同意一个客户端请求时,服务器端SOCKET形成一个服务器连接。当服务器端同意连接时,向客户端发送一个服务端socket描述以完成连接,当客户端socket收到这个描述时这个连接得到确认,连接完成。一但连接到客户端的Socket完成,服务端连接就不能识别从别的客户端发来的连接。 一个完整的SOCKET连接描述,你必须提供SOCKET 在连接两端的地址,并且在连接前,你必须完整的描述你想得到的连接。客户端SOCKET必须描述他们想连接的服务器。服务端
27、SOCKET必须描述他们提供反应的服务器的端口。一个SOCKET 连接终端的完整描述包括两部分:1.IP地址 主机是这样一个系统,它运行着包含有SOCKET的应用程序。你必须给SOCKET描述主机,通过给出主机的IP地址来完成这个描述。2.端口号虽然IP地址提供了足够的信息去找到SOCKET连接中位于另一端的系统,但通常还需要指定那个系统的端口号。没有端口号,一个系统在同一时间只能进行一个单一的连接。端口号是唯一标识那个允许一个独立系统连接到同时支持多个连接的主机,每个连接都必须指定一个端口号。在delphi中开发SOCKET网络程序,可以使用clientsocket和seversocket组
28、件,或者使用Indy控件组中的TIDTCPClient和TIDTCPSever组件(本次毕业设计中采用了前者)。不过在delphi7.0这个版本中,这对组件不是默认安装的,需要手动安装,会安装在internet组件页中。(socket控件使用windows socket对象去封装windows socket API 调用,所以应用时不用去关心连接建立的细节或管理socket信息)。3.2 clientsocket和seversocket控件Clientsocket是客户端组件,而seversocket是服务端的组件。通信中由clientsocket主动请求服务器端建立连接,而seversock
29、et是通信里的响应方,其动作是监听以及被动接受客户端的连接请求,并对请求进行回复。而它同时可以接受一个或多个clientsocket组件的连接请求,并于每个clientsocket进行单独连接和通信。在属性上,只要保持服务端port和客户端的host一样既可以正常工作。由于我做的是客户端,所以下面详细的论述客户端clientsocket的属性:l Active:标识套接字底层连接是否打开并且处于激活状态;l Address:指定服务器系统的IP绝对地址;l Host:指定服务器系统的主机名(如果同时设置了Host属性和Address属性,则系统优先使用Host属性);l Port:指定服务器系
30、统的端口号;l ClientType:指定客户读写信息类型,应该与服务器的设置相同,ctNonBlocking表示异步读写信息,ctBlocking表示同步读写信息;l Close:关闭套接字连接;l Open:打开套接字连接;l ReceiveBuf:从套接字连接中读取指定的节数并保存在缓冲区buf中;l ReceiveText:从套接字连接中读取一个字符串,其函数原型:Function ReceiveText:string;l Sendtext:向套接字连接发送一个字符串;l ReceiveLength:返回将要发送的字节数,其函数原型为:Function Receive Length:I
31、nteger。而在测试服务端连接是否正常是,可以自己建一个服务端,使得两者之间相互通信,在使用过程中注意:1. client和server都有port属性,需要一致才能互相通信;client有Address属性,使用时填写对方(server)的IP地址;2. client: OnRead事件,当client受到冲击消息时在OnRead事件中可以获得server发送过来消息。Server: OnClientRead事件,与上述client的作用相同;3. clien使用SocketClient1.Socket.SendBuf(char类型的数组,信息长度);server使用SocketServe
32、r1.Socket.Connection0.SendBuf(char类型的数组,信息长度);4. clien使用SocketClient1.Socket.ReceiveBuf(char类型的数组,信息长度);server使用SocketServer1.Socket.Connection0.ReceiveBuf(char类型的数组,信息长度)。3.3利用SOCKET完成消息传送SOCKET是两台计算机通信的终节点,使用网络协议进行通信。SOCKET与其他I/O设备类似,对它的操作也包括打开、读取/写入及关闭等。SOCKET通信在windows中是以队列的形式有操作系统进行处理的,而且接收方和发送
33、方是相互协同工作的,否则会造成数据丢失,SOCKET编程采用的是网络通信方式,同时遵循数据分包传送的基本规则,也就是说,在SOCKET编程中,每次只发送和接收一个包,以确保数据传输的安全性和稳定性。在整个邮件发送中,利用SOCKET通讯完成连接和消息发送应该说是我毕设的一个前置一个前提。这样的连接和消息发送再后来的设计中会被压缩,因为和服务器是按照SMTP协议进行交互的。但是从整个过程来看是很重要的,完全有必要做一次连接和消息发送。图3-1是我在连接虚拟服务器和发送信息时的工程截图:图3-1 工程截图主要还是seversocket和clientsocket两个组件,在这两个控件的port属性,
34、需要一致才能互相通信;client有Address属性,使用时填写对方(server)的IP地址。这个是这个过程中所需要注意的。下面是程序中实现消息发送的一段:procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);begin if key = vk_return then if FServerFlag thensskServerSocket1.Socket.Connections0.SendText(Memo1.LinesMemo1.Lines.count - 1) else cskCl
35、ientSocket1.Socket.SendText(Memo1.LinesMemo1.Lines.count - 1);end;在程序运行后,按下回车键使得向客户端发送消息。图3-2是我在运行程序时结果的截图:图 3-2 消息发送截图在运行中,首先要连接服务器,而这个服务器是由seversocket构建的虚拟服务器,所以这个IP地址是本地主机的IP,然后在Memo1中输入helo按下回车键,服务器端则在Memo2中读出了我发送的信息。这说明消息发送是正常的成功的。而在这之前的连接服务器,就是clientsocket主动发出连接请求但是它的port属性一定与seversocket的host属
36、性一致。这样就完成了一个客户端和自己的虚拟的服务端的连接,达到了最初的目的。3.4 基于SOCKET协议下SMTP邮件发送过程 在计算机网络中,计算机与计算机之间可以完成资源共享、数据传输等任务。而在这个过程当中,存在着这样两种情况:一种是请求服务,另一种则是提供服务的,这种主从关系被称为客户/服务器模型(即Client/Server模型,常简写为C/S模型)。而在邮件发送的过程中也同样遵循这种模式。客户端可以通过网络向服务器端发出服务请求,当服务器端接收到请求后做出响应,然后再通过网络将响应传回到客户端。显然我的毕设课题是做的客户这一端。用户在发送电子邮件的时候,电子邮件首先被发送到ISP(
37、Internet Service Provider,互联网服务提供商)的邮件服务器即通常说的SMTP服务器,并被放在收信人邮箱中,收信人上网后,可到邮件服务器进行读取。从这可以看出,电子邮件系统应包括电子邮件收发程序、邮件服务器以及电子邮件使用的协议。在应用层,SMTP协议是用来解决电子邮件发送的问题的,POP3(Post Office Protocol 3,邮局协议的第3个版本)和IMAP(Internet Message Access Protocol,因特网报文存取协议)是用来解决电子邮件接收的问题的。而根据这些我们可以大概的想象出电子邮件从发送到最后接收的一个具体的过程和概型:从发件人
38、发出邮件,到SMTP邮件服务器,然后转发到POP3邮件服务器中,最后由收件箱从中提取发来的邮件。也就是说,我们在整个过程中,需要经历至少两个服务器作为中转,一个SMTP服务器一个POP服务器,SMTP服务器负责接收发送来的邮件并转发到POP服务器中,然后再由POP服务器再由收件箱的用户提取邮件。而在本次的毕设要求中,我所需要做的是第一步,把邮件发给远端服务器,而接下来的工作将由服务器完成,直到最后邮件发给收件箱。总结而来,整个邮件的发送的第一步基本是以下几个步骤:(1)建立与服务器的连接。(2)客户端发送HELO命令以标识发件人自己的身份,然后客户端发送MAIL命令;服务器端正希望以OK作为响
39、应,表明准备接收(交互的开始)。(3)客户端发送RCPT命令,以标识该电子邮件的计划接收人,可以有多个RCPT行;服务器端则表示是否愿意为收件人接收邮件。(4)协商,包括用户请求登录、计划的发件人和收件人,得到服务器的允许之后,开始发送邮件,用命令DATA发送(请求发送邮件数据)。(5)以“.”号表示结束输入内容一起发送出去,结束此次发送,用QUIT命令退出(邮件发送完成)。注:CR:= LF:= SP:=4 程序实现本次设计完全是个软件上面的东西不涉及硬件方面,图4-1是我delphi中的工程设计:图 4-1 系统工程的全体截图4.1 交互实现与邮箱SMTP服务器的交互是建立在SMTP(简答
40、邮件传输协议)之上的。SMTP目前已是事实上的在Internet传输E-Mail的标准,是一个相对简单的基于ASC文本的协议。在其之上指定了一条消息的一个或多个接收者(在大多数情况下被确定是存在的),然后消息文本就传输了。可以很简单地通过Telnet程序来测试一个SMTP服务器,SMTP使用TCP端口25。要为一个给定的域名决定一个SMTP服务器,需要使用MX(Mail eXchange)DNS。正是在这个标准之下,按照标准所规定的内容和顺序与服务器从连接到一步一步的交互最后发送邮件。SMTP是工作在两种情况下:一是电子邮件从客户机传输到服务器:二是从某一个服务器传输到另一个服务器。SMTP也
41、是个请求/响应协议,命令和响应都是基于ASC文本,并以CR和LF符结束。响应包括一个表示返回状态的三位数字代码和可选解释说明。SMTP在TCP协议25号端口监听连续请求。4.1.1 从连接服务器到AUTH LOGIN在本次电子邮件发送网关设计中,客户端与邮箱服务端的交互是整个设计的核心。这个交互完全体现了从套接字底层分析SMTP协议的过程。交互是个一步一步完成的工作,每次的交互只能向服务器发送一个包即一个请求,然后由服务器返回一个响应,告诉你刚才操作是成功的还是失败的。由于目前的邮箱服务器一般都由SMTP服务器升级成为了ESMTP服务器,两者之间的区别很小,主要是在向服务器发送标示用户身份上:
42、前者的请求是HELO,然后就可以向服务器发送其他的请求进行交互;而ESMTP在用户单单之HELO之后是不能成功与邮箱服务器进行其他交互的,此时HELO之后必须添加一个EHLO,与服务器有一个EHLO的过程,在这之后可以成功地与服务器进行其他的交互(由于EHLO也同样具有HELO的功能,所以在具体的交互过程中,也可以把惯用的HELO这一步省略了)。与邮箱SMTP服务器的连接,是和clientsocket的Active属性密切相关的。Active属性:指示套接字连接是否打开和可用,使其他计算机与其通信。使用或修改套接字连接前,应该读取该属性确定连接是否打开并且准备就绪。对于客户端套接字,设置该属性
43、可以打开或关闭到另外一个计算机的套接字连接;对于服务器套接字,可打开或关闭监听客户请求的套接字连接。语法:Property Active:Boolean;在设计阶段,该属性为false,程序启动时将打开指定的套接字连接(即属性改为true);程序运行时,可调用Close方法连接,调用close方法关闭连接。在这次毕业设计中关于与邮箱SMTP服务器的连接,我设置了两个button一个连接一个断开,对应的程序分别是:ClientSocket1.Active:=true;ClientSocket1.Active :=false;而在同时利用一个Timer1Timer控件在Label显示连接是否成功,
44、是处于断开状态还是连接状态,对应的关键程序:if ClientSocket1.Active THEN LABEL2.Caption :=连接成功 else label2.Caption :=尚未连接;图4-2是我的程序运行连接时的截图:图4-2 连接SMTP服务器的截图在上面的截图中根据服务器返回的信息以及label显示的“连接成功”的信息,可以说明连接服务器是成功的.而断开连接就直接在程序运行时按下“断开”的按钮,就可以断开连接。每一次的与邮箱服务器的交互,都是始于标示用户身份开始,即是向邮箱服务器发送HELO,它是每一个交互的前提,你得向邮箱SMTP服务器声明你是一个合法的用户而不是一个欺
45、骗者。这也是SMTP协议里防止垃圾邮件的一个基本的方法,杜绝与服务器连接的不是一个为了发送垃圾邮件的而写好的程序。支持SMTP服务扩展的客户应该以EHLO命令开始SMTP会话,而不是通常的HELO命令。如果服务器也支持,那就返回确认响应,如果不支持就返回失败响应。因为引入了EHLO命令,因此会话开始的第一条命令可以是HELO或EHLO。虽然EHLO关键字可以是大写,小写,大小写混合的,但是对它的处理是大小写敏感的,这是与原来规定不同的。所以为了统一方便,在我的毕业设计中都是使用了大写以防出错。EHLO之后便是请求登陆,即AUTH LOGIN,这是个简单的请求,只是向服务器申请用户登陆,但却是邮
46、件发送的必由之路!如果你不能成功登陆自己的邮箱,那么你就没有资格得到服务器的同意让你去发送邮件。4.1.2 BASE64加密认证用户及密码用户账号的认证和用户密码的认证是在向SMTP邮箱服务器AUTH LOGIN成功后向服务器发出的请求。在这两个交互里,交互的本身并没有特别,特别的是他们的交互不是明文,而是需要加密的。作为MIME的默认编码标准,所以在SMTP协议里,规定了加密方式采用BASE64加密的方式。按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别6位字节的形式。BASE64具体编码加密时是根据它的编码表(
47、附于最后的附录里面)一一映射编码的,具体的编码程序如下:1. 将要加密的文本的每个字符转换成标准的ASCII十进制码。2. 通过任何一种方式(手算、机器算、对照表格)将这部分十进制编码转换成二进制(文章最后附有转换表)编码。每个十进制码都对应器等价的八位二进制数值。3. 将这部分二进制数连结到一起,产生一串二进制数。4. 将这一大片的二进制字符串分割成每6个字符为一部分的小块。5. 通过任何一种方式(手算、机器算、对照表格)将这部分6字符的小块分别转换成相应的等价十进制数。6. 通过Base64表转换成Base64编码。当然BASE64编码是个非常抽象的过程,下面举一个例子:对ABC进行BASE64编码1. 首先取ABC对应的ASC码值A65 B66 C672. 再取二进制 A(0100 0001) B(0100 0010) C(0100 0011)3. 把这三个字节的二进制码接起来 0100 00