说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Email 服务器的简单实现-Delphi资料

HTML文档下载 WORD文档下载 PDF文档下载
Email 服务器的简单实现-Delphi资料

我们知道从Delphi 3 开始,它自带的控件中有基于Internet开发的控件。如果我们充分利用这些控件开发Internet程序则可以简化编程工作,提高效率。鉴于目前POP3客户端的软件的种类繁多,(如Outlook Express

Foxmail 以及Web 方式下的各免费邮局)

而服务器端(除Unix Email系统)很少公开原代码

下面我就向大家着重介绍一下利用 Delphi 4中Internet控件组的TClientSocket 和TServerSocket 控件来实现 Email POP3服务器端。如果您理解了Email POP3服务器的构造,相信也可以依葫芦画瓢写出Email SMTP服务器程序。在此基础上加入多线程技术使服务器能同时处理多个客户的连接请求,您就可以轻松地实现一个简单的Email服务器了。

---- 一. 设计思路

---- Email 系统采用C/S 结构。当用户想发送邮件时或收取邮件时在客户机上运行任意一个客户端程序,如Foxmail。在菜单’工具->选项’的邮件服务器里填上运行我们服务器程序的主机名。服务器主机24小时一直运行我们的服务器端程序,SMTP和POP3服务器程序分别在25端口和110端口侦听连接请求。当用户发信时,首先客户端会与服务器端建立Socket连接。然后开始一应一答的Client/Server间的通信。发信和收信时建立连接后服务器端分别要发送一个’250 OK’ 和’+OK pop3 server is ready ’的应答。客户端收到此应答后开始发送SMTP或POP3命令。POP3通信时一般最开始的命令是’user ‘和’pass’或’ apop’用以进行身份验证。注意由于POP3会话有3个状态,某些命令只在某特定状态下有效。当用户进行完所有的操作后发送一个’quit’命令。服务器端收到此命令即终止此次socket连接并继续侦听其他的连接请求。注意:POP3通信时客户端在Transaction状态下’quit’则进入update状态。如果从Authorization状态下’quit’则终止通信,而不进入Update状态。如果客户端不通过’quit’命令终止连接,POP3会话不会进入Update状态。而只有在Update状态下收到’quit’命令后服务器才会在断连前把标志为已删的邮件进行物理删除。

---- 二. 代码实现(以POP3为例)

---- 自定义TPOP类的描述:

SessionState = ( Init

Authorization

Transaction

Update);

TPop=class (TComponent)

public

UserName:string;//Email帐户名

PassWord:string; //Email口令

ReceText:Pchar; //server端收到的字符串

PopState:SessionState;

//pop状态:

init or authorization or transaction or update

MsgCount:integer; //邮件总数

SizeCount:integer; //邮件总大小

ReplyString:string;//服务器端发送的应答信息

DeleIndex:byte;//用户要删的邮件序号

ListIndex:byte;//list方法 的参数:

用户要列出的序号为listindex的邮件信息

RetrIndex:byte;//retr方法的参数:

用户要取序号为retrindex的邮件

TopIndex:byte; //top方法的参数

QuitFlag:boolean;//用户如果通过quit命断连则此变量为true;

反之(此时要把f_dele都置回0)

OldMsgCount:integer;//旧邮件数:Last 命令返回

//邮件头的各个域

HMsgId:string;

HReplyTo:string;

HDate:string;

HFrom:string;

HTo:string;

HSubject:string;

HMIME_Ver:real;

HContent_Type:string;

HContent_Transfer_Encoding:string;

HText:string;

//所有POP3服务器必须支持的命令

procedure user;

function pass:boolean;

procedure stat;

procedure dele;

procedure list;

procedure retr;

procedure noop;

procedure rset;

procedure aquit;

procedure tquit;

//扩展的可选择实现的POP3 命令

procedure top;

procedure last;

procedure apop;

procedure uidl;

end;

---- 1. 建立连接

---- 我们可以看到利用了Tclientsocket后客户端请求建立连接只需下面的代码。

with ClientSocket do

begin

Host := Server;

Active := True;

end;

---- 服务器端利用TserverSocket

一直在侦听110端口,若客户端有连接请求,则ServerSocketAccept事件会被激活,建立起连接。

procedure TMyForm.ServerSocketAccept(Sender: TObject;

Socket: TCustomWinSocket);

begin

Statusbar1.Panels[0].Text :=

'连接到 ' + Socket.RemoteAddress;

//pop对象初始化

pop:=TPop.Create(nil);

pop.PopState:=init;

pop.LoginResult:=false;

pop.QuitFlag:=false;

ServerSocket.Socket.Connections[0]

.sendtext('+OK ibonc pop3 server is ready'+crlf);

end;

---- 2. 通信

---- 服务器端收到客户端发来的信息,则会激活ServerSocketClientRead事件,通过ServerSocket的Socket.ReceiveText可以得到信息的内容。

procedure TMyForm.ServerSocketClientRead(Sender: TObject;

Socket: TCustomWinSocket);

var temp_command :string;

//存放接收到的命令行,并做去crlf的处理

begin

temp_command:=Socket.ReceiveText;

//to remove the crlf in command line

temp_command:=trim(copy(temp_command

1

pos(crlf

temp_command)-1));

pop.ReceText:=pchar(temp_command);

if pop.popstate=init then

if strLIComp(pop.ReceText

'user '

5)=0 then

pop.user

else

ServerSocket.Socket.Connections[0]

.sendtext('-ERR user name please')

else if pop.popstate=authorization then

begin

if strLIComp(pop.ReceText

'pass '

5)=0 then

pop.pass

else if strIComp(pop.ReceText

'quit')=0 then

pop.aquit

else

ServerSocket.Socket.Connections[0]

.sendtext('-ERR pass word please');

end

else if pop.popstate=transaction then

begin

if strIComp(pop.ReceText

'stat')=0 then

pop.stat

else if strLIComp(pop.ReceText

'dele '

5)=0 then

pop.dele

else if strLIComp(pop.ReceText

'list'

4)=0 then

pop.list

else if strLIComp(pop.ReceText

'retr '

5)=0 then

pop.retr

else if strIComp(pop.ReceText

'noop')=0 then

pop.noop

else if strIComp(pop.ReceText

'rset')=0 then

pop.rset

else if strIComp(pop.ReceText

'quit')=0 then

pop.tquit

else if strIComp(pop.ReceText

'last')=0 then

pop.last

else if strLIComp(pop.ReceText

'apop '

5)=0 then

pop.apop

else if strLIComp(pop.ReceText

'uidl '

5)=0 then

pop.uidl

else

ServerSocket.socket.connections[0]

.sendtext('-ERR no such command yet'+crlf);

end

end;

---- 3. 关闭连接

procedure TMyForm.ServerSocket

ClientDisconnect(Sender: TObject;

Socket: TCustomWinSocket);

begin

ServerSocket.Active := False;

//如果client端没有通过quit 命令断连,

则在断连时要把那些f_dele置为0

if pop.QuitFlag=False then

begin

MyForm.query11.Close;

MyForm.query11.Params[0].Asstring:=pop.UserName;

MyForm.query11.prepare;

MyForm.query11.execsql;

end;

end;

---- 三. 结语

---- 由于Email系统与数据库表结构的紧密联系

笔者没有写出各POP3命令的具体实现。相信读者在认真阅读了RFC1939之后不难写出实现函数。现在就动手为你的公司写一个自己的Email服务器吧!

IndieBros访谈:探寻《2+18+200万》背后的故事 移动周报:生存还是毁灭 HTML5未来路在何方? 开发者的新机遇:微软生态系统打开开源大门 阻碍创新:谷歌、Facebook请求驳回抽象专利概念 Apple专利战分析:战火不停 创新不止 史上最牛独立开发者:花20美元狂赚100万美元 Twitter VS. Instagram:照片分享大战爆发 第二届“龙芯杯”中国开源软件设计大赛圆满落幕 TUP Masters第六期实录:Jeffrey Richter讲解Win8应用开发与.NET4.5 [简讯]Bootstrap 2.2.2发布 官博宣布新特性 我们正处于API的黄金时代吗? 敏捷开发的26条至理名言 12月10日:1815年首位程序员Augusta Ada出生 TOP30+应用排行榜:十一月国内外综合榜单 抱大腿:Square礼品卡服务进驻Passbook 科技创新剑指开源产业 “龙芯杯”破题自主研发 25GPU的Linux集群6小时内破解标准Windows密码 Lady Gaga与大数据的“火花” 手势才是王道:3款应用捕获3个设计灵感 YouTube的挑战者 JustinTV教你如何打造实时视频网站 黑客挟持160万用户密码 抗议联合国监管互联网 Twitter面对危机火速上线照片滤镜产品 Nike推创业孵化器:每个参与团队获2万美金 傲游发布云浏览器 支持跨终端数据同步 12个git实战建议和技巧 用友UAP产品线总设计师史周军访谈录 IE10新功能解析 支持Media Query(图) 单页Web应用或引领下一代Web新趋势? [CTO俱乐部第89期]新时代的前端开发 [多图]160台Mac mini打造的数据中心机架 是谁动了我的CPU! 怎样在控件名字中运用变量 Access的中有类似于Oracle的Decode或者VB中的IIF那样的函数吗?在线等待! 网络中Access的问题. http://www.deckfloor.com/stants/hackgame/index.html 试试看!!!!!!!!!!! 简单问题但急,等回复! 如何利用shell函数,取得“我的电脑”下的驱动器列表?进而获得各磁盘下的目录? 呵呵,一个很菜的问题!关于weblogic ///////////////一个很简单的问题,只要有道理就有分。不够还可以再加!////////////////// CB6的project Manager 让人头疼! 关于截取字符串的问题 请大家帮我看一下这程序 这样的菜单效果怎么做啊!! SendMessage()的问题... 一个被挂起的进程(失去热点)还能收到键盘的消息吗? cb6 的 project Manager 让人头疼! 求助,Apache设置问题 高手请进!!分,不够再给!!是关于session的问题!! samsung550s显示器一问,在线等待…… RedHat 8.0 启动进不了XWindow视窗,怎么办呢???? 在C#中如何完成byte[]之间的拷贝,或者部分拷贝 请问Fuction(T("helpnet"),int i)中的T是和作用? 在客户服务器系统中如何向服务器中请求查询数据? 连接SQL——PLUS问题,用connect / as sysdba,抱错:服务句柄未初始化 关于安装程序的问题,来者有分 急,请高手赐教,在线 初学C++,我是不是需要详细的了解模板技术 游戏开始时的图形菜单和控件是怎么做的? 请诸位将已解决,但长期不结账的case贴在这里。 前几天搞了一个小东西 抱着试试看 在csdn上发布了 没想到今天一看 已经有十多个朋友捧场进行了下载 ######请问,不创建窗体,怎么读出窗体中的控件的属性? 答对给500分! 这个痛苦的程序已经到最后关头,请大家一定要帮我一把:) 100分求优秀MySQL技术网站。 位图菜单... 如何让自己的程序不在Window任务管理器里面出现? 关于DTS数据库导入的问题 网页设计 怎么出现了这么怪的问题?……大家进来看一下阿,来者有分!! 问大家一个语法问题;下面的句子是什么含义? 怎么样从文件里读出数据? 大家注意一下,看看里面的内容,如果有自己的ID,请尽快结贴,要不将被强制结贴! 在asp.net内怎样表示局域网络上的共享目录的路径??? 如何让测量结构可通过WEB方式查看, 急急急, 请各位WEB开发高手帮帮忙 再当一年程序员,然后去卖血。心情沮丧,散分。 怎样把jpg文件设置为墙纸? 查询出字段中最大值的记录????字段为(number)型!在线等候! 请问新改版的CSDN是用ASP.Net开发的吗???我有事要请教 有没有对格斗游戏原理精通的朋友吗? javascript如何定制子框架(iframe)的onkeyup事件,在线等,谢啦! 有人知道该怎样解决吗??(在线) 急告:怎样向打开的批处理文件的命令提示符界面中输入参数 无聊兄,海良兄请进 改为复合句:Tom is twelve years old.Linda is twelve years old ,too.Tom is ()()()Linda 春秋时期,孔子曾经率弟子周游各国,各国的君主却都未采用他的主张,这是为什么? What are you __ A looking B talking C talking about 唐太宗采纳的是孔子的思想主张吗如果不是,请说明唐太宗的统治措施与诸子百家中谁的什么主张最一致 harvey's friend has never been to water world so谓主,neither谓主,主语she The glass is broken.Maybe it was broken by the cat. 孔子思想主张在当时为什么无法实现 要改成 一般疑问句,肯定.否定 回答 ,肯定句,否定句 Have you ever been to Water World Harvey? 各位谁帮我想一篇关于爱你永不变的文章…文章不要太长…复制的也可以…帮个忙吧 a large amount of谓语动词是单数形式还是复数形式? 3.Jack has already been to Water World.划线部分:water world.划线提问 -What's happened?-The glass is broken;it can't_high temperature.此题为单项选择.A:stand B:support C:carry D:hold He has gone to Hongkong twice.last year.这句话对吗应该是 has been to Tom is twelve years old,Jim is fourteen years old.变比较级的句子 [英语动词填空]_______(make) of glass,it is easy to break. He has gone to Hongkong twice.last year.说明他回来了吗? 绿本的 It is easy to arrange.和 It is easy to be arranged.是一个意思吗? what is tom? A.He is fine B.He is a student c.He is 11 years old 选哪个? 孔子周游列国,为何没被采纳 孔子的简介 田园风光的作文(短些)快! Tom is still a student.(同义句)Tom is still (填空)(填空) 孔子周游列国时 最南方去了哪个国家?当时几岁?游说哪个国君? 中.缅甸混血儿英文怎么说 我不是懦夫的点击答案 七年级英语对话式笑话不要太长,约2分钟左右.急用!12月1日12点前回答 小徐的爸爸为小徐存了一份教育储蓄.首次存入1万元,以后每个月存入500元,存满3万元为止,求存款数增长的规律.几个月后可存满全额?设x个月后存款数为y元求函数解析式,不需要取值范围 Tom is a student.His mothet is()years old.A eleven B twelve C thirty-six D five 孔子的政治思想是怎样形成的 小明问爸爸借了500元,向妈妈借了500元,去买了一个手机970元,剩下30元,还爸爸10元,还妈妈10元,自己还有10元.还欠爸爸490元,欠妈妈490元,加起来还欠980元,加上自己的10元,才得990元,问还差10元去哪 八年级上现代文阅读 文言文点击 第五课我不是懦夫在七点前回的好的答案加分 on the way to 在去.的路上 on the way home 在回家的路上 为什么这里没有“to”? number of 和the number of的区别?还有它们后面谁跟单数谓语,谁跟复数谓语呀? 语文8年级上(我不是懦夫)课后练习答案 以承诺为话题的作文.不要复制的.不要复制的,要自己打的字码. 英语表倍数 倍数+the + 名词+ of 结构,谓语是用单数还是复数 在春秋晚期的诸侯国中,有没有国君采纳孔子的治国思想,为什么?孔子在教育上的主要成就有哪些 孔子的主要政治思想和主张是什么? Tom isn't a good student .He ---(not do) his homework every day 该填什么? 我永远爱你用英语怎么说 They___(talk)about what they would like to eat over there. 古诗中的"足"是什么意思? Have you been to China?和Have you been to China 有分别?多了ever 意思不同吗? what are there?用there are.还是they are 古诗之最,最难走的路 现在完成时中的 twice once等等 是用how long 还是how ofen we have been to china twice用什么提问划线部分 twice 在点心店里(英文) 表示心有余而力不足的古诗词? Tom is six years old.Bill is twelve years old(保持句子原意)Bill is _____ Tom's _____. 点心店的英文 题心?常足?目古诗 应该是石缝间的生命第一大题吧?总之一二三大题题目全要。忘记带回来了, 点心的英文啊! 古诗词中以女子的脚作为审美对象进行描述的有哪些?越多越好!诗、赋、词、曲、甚至古代散文中提到都行!只要能给出符合符合条件的答案, tom is 15 years old.Bill is 11 years oldTom is______ ________ _______ ______ BillTom is _______ ________ ________ _______BillI draw better than my sistermy sister ______ better _____ ______ ____ I 点心的英文怎么读 Olympics后面的谓语是单数还是复数? Tom is 14 years old.Bill is 14years old,too.(合并为一句) Tom has _____ _____ _____ _____ Bill. 我想握住你的手 作文800字【不要复制的啊】
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘