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

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服务器吧!

CMDN Club 25期:knewone与路况电台的精益创业法则 Windows Blue的孪生兄弟?Office Gemini浮出水面 HTML5开发平台Ludei将支持3D游戏开发 《二战风云》发布至今,已为顽石互动狂赚2.7亿 腾讯开源基于HTML5技术的专业级图像处理引擎 AlloyImage Linux容器运行时Docker开源 360上线第三方漏洞收录平台 将现金奖励爆料者 UC推出iOS平台首个支持WebGL的浏览器 魔兽之父专访:今年游戏产业会出现一场革命 Instagram 5位传奇工程师背后的技术(PPT全译) Google云计算专家Jeff Dean与Sanjay Ghemawat获ACM Infosys基金会大奖 谷歌承诺不对开发、发行和使用开源软件的人专利诉讼 Web框架排行榜 Netty、Servlet和Vert.x位列前三 DARPA慷慨解囊的背后:Python与大数据的火花 研发周报:神奇!1KB JavaScript代码编写的3D蜜蜂 移动周报:65岁传奇Android工程师谈开发 “部落战争”开发商Supercell融资1亿美金 投资公司争先恐后 Kiip 90后华裔励志故事:从遭解雇到誉满全球 大数据基因测序的成本逼近1000美元:个性化医疗的时代来临 携程开放平台发力 将实现旗下产品全流程API支持 Puppet labs发布2013自动化运维报告 “国”字号开发者:航旅纵横负责人薄满辉专访 金山云杨钢:核心算法保证安全和低成本 加速软件交付 企业级模拟测试服务CA LISA受追捧 盛大云业务重点转向自服务 转战中小型企业:Prediction API请求一个月内飙升至7亿多次 利用光子 耶鲁大学研究人员让量子计算机离现实更近一步 技术为王的云计算会让IT部门消亡么? 从Discuz到APP:安米移动社区转化工具 覆盖全领域:Google、Facebook、Twitter等大师的最佳推荐 苹果CEO宣布更改保修政策 并向中国用户道歉 form提交数据后,另一页取值为空?200分相送!! 关于windows.net server的安装 打印问题!!(50) 如何编程获得win2000本机的MAC地址?不用Netbios的方法阿,谢谢 讨论一下,对于个人来讲计算机可以帮助我们做什么? 谁有WS-FTP pro 7.5的注册码! 怎样改变MENU的字体? 请问有谁愿意转让《Object-Oriented Software Engineering: A Use Case Driven Approach》一书 讨论一下,对于个人来讲计算机可以帮助我们做什么? 谁用C++ BUilder写过类似sql 语句生成器的东西。 有谁知道 NetBoy 3.0.1 的序列号?第一个答对者20分全给!本人说话绝对算数。 ADO,如何判断一个连接对象(_ConnectionPtr)是否已经打开? IIS 5.0 & exchange server 有沖突? 修改数据库问题,急,在线等待! 讨论一下,对于个人来讲计算机可以帮助我们做什么? 怎样实现c语言对数据库的操作?(查询,添加,删除,排序。。。) 建立ActiveX控件的问题 求救:java的‘主要类型’本质上是不是对象? 如何编程实现改变显示器的分辩率? 有谁知道 NetBoy 3.0.1 的序列号?第一个答对者20分全给!本人说话绝对算数。 请大家给个方案:关于中文词法分析? 请 newly_ignorant(不学无术) 兄进来领分 怎样控SourceSafe的物理权限 ? 向各位高手求助!简单goto转变成没有goto的语句· 怎么改变DataGrid页导航条数字颜色 谁有IPX在局域网里收发和解析IPX包的例子! 释放连接,在线等待 我想将一个表中的所有字段的内容送入word中规定的表格中,请问谁能给出一个例子??? 如何删除folder.htt,和desktop.ini文件? ADO问题 为什么用 filelistbox 写完的程序换到其他的机器上就不好用了? JB7编译的exe文件为什么不能运行 vb调用存储过程(mssql,oracle),是否一样?不一样怎样做到一致?! 学习ASP STL问题2,怎样获得元素在list中的位置(序号)呢?? 法国人为什么不喜欢说英语 热烈祝贺 张一飞(intfree)、侯启明、俞玮 夺得 IOI 2002 金牌! 我在2000下写的程序在2000下能正常使用,但在98下出现错误!为什么? 怎样实现c语言对数据库的操作?(查询,添加,删除,排序。。。) Listctrl问题 dim objconn as ADOconnection 提示出错 哪位朋友有SnagIt(V5.2.1)的注册码? think in java里一段关于snake.java的程序没看懂,请大家给解答一下,谢谢 一个常用的简单问题?请帮忙。(本人刚从asp转过来) 为什么程序突然跳到00000000? 有谁知道 NetBoy 3.0.1 的序列号?第一个答对者20分全给!本人说话绝对算数。 谁有这样的算法:给定两个区域,用直线或折线来连接,以及移动其中线段的算法。 UDP高手:建立了一个服务器后,如果。。。 用ISAPI编程怎么实现文件的传输(象网络硬盘那样的功能) OpenGL与C++Builder 请问在ORACLE中如何列出所有用户创建的表存储过程等? 复习计划书? 三峡大坝刷新了哪些世界之最? 光补偿点时叶绿体中ATP的去向?线粒体中二氧化碳的去向? B淋巴细胞与记忆B细胞分化成浆细胞所用时间不同,为什么? 若a为有理数,试比较a与1/2a的大小 有丝分裂,染色体变为2条染色单体是在前期还是间期? 成语掩耳盗铃这故事告诉我们什么道理? 求哲学中 旧唯物主义的反映论和旧唯物主义认识论 的概念 怎么区别有丝分裂的分裂间期和分裂期染色体、染色单体和DNA数目 有丝分裂为什么染色单体是逐渐变成4n的如题 问一道线性代数证明题 求教会的朋友 如题 旧唯物主义认识论与辩证唯物主义认识论的区别在于是否坚持反映论 45度弯头怎么计算长度 用四边长8厘米的正方形,拼成一个大正方形,这个大正方形的面积是_厘米 唯物主义认识论,唯物主义反映论,唯物主义辩证论的区别 抗震锚固长度怎么计算 这个故事的寓意是什 3.如何理解辩证唯物主义认识论是能动的反映论?它和唯心主义认识论、旧唯物主义认识论有什么区别? 可以先发P18页修改病句的答案,我很着急, 集成吊顶还是木工做吊顶啊,哪个会比较好啊 辩证唯物主义认识论把实践引入认识论,把辩证法贯彻于反映论.正确 错误 关于锚固长度计算的问题最好帮忙多举几个例子!说的越详细越好.话越白越好. 什么是姐妹染色单体? 国家规定的住户用电每平方多少瓦 小学语文总复习计划 一个长方形的面积是240平方厘米长和宽的厘米数是相邻两个自然数长和宽是多少厘米 每年平均用电多少瓦全世界每年平均用电多少瓦 ? 锚固长度怎么算 生物有关染色体,染色单体,姐妹染色单体 笔记本一般用电是多少瓦 语文实践活动复习训练题(求答案)1、班级举办手抄报活动,你为你的小报起的名字叫《_______》,你的小报的栏目有:________、________、_________等.在这次办报中,你一定有很多收获,你的收获是__ I like to sleep ___longer in the morningA.more B.very C.a little D.many 家庭用电220伏等于多少瓦? 在平行四边形ABCD中,点E,F在AC上,且AF=CE,点G,H分别在AB,CD上,且AG=CH,AC与GH相相交于点O,试说明,EG//FH,GH,EF互相平分 选择填空 1.I like ____ a little longer in the morning A .sleep B.sleeps C.to sleep D.sleeping2.I am the last one _____to school.A.get B.gets C.to get D.go 在下列实验中,必须始终用活细胞做材料的是 A.用光学显微镜观察植物细胞有丝分裂 B.用光学显微镜观在下列实验中,必须始终用活细胞做材料的是A.用光学显微镜观察植物细胞有丝分裂B 关于体液免疫,B细胞分化为浆细胞的过程课本说大多数抗原经过吞噬细胞的摄取和处理,刺激T细胞产生淋巴因子,少数抗原直接作用B细胞.老师说两者缺一不可.可只有一小部分的接受了抗原刺 I like to s_____ a little longer in the morning 借助光学显微镜,可以详细观察活细胞有丝分裂全过程 浆细胞能够分化的原因都是什么? do you like _____a little longer in the morning.为什么用to sleep而不是sleeping 如图,在半径为R的半圆里,AB为直径C,D是半圆的三等分点,求图中阴影部分面积 有丝分裂中期染色体是2n个,染色单体是4n个吗?rt 英语考试 I like to s———— a little longer in the morning.1.I like to s———— a little longer in the morning.2.We eat —— supper late in the evening.A.a B.an C.one D./3.翻译句子我观看电视的早间新闻.I watch the early _ 如图,C、D是以AB为直径的半圆上的三等分点,半径为R,求图中阴影部分的面积 (要具体过程) 以二倍体生物为例 有丝分裂的后期 其染色单体从4n向0变?可以说这个时期染色单体为0了?就是如果有题目问 有丝分裂的后期 染色单体数目为—— .是不是填0 还是填4N 边长是8厘米的大正方形,剪成4个相等的长方形,长方形的周长是多少 同底数幂的乘法与同底数幂的除法区别联系 已经是期末了,我准备开始复习、练习和巩固.请问该怎样制定复习计划?注:只有14天时间,越快越好.急,急, 四个一样的长方形和一个小正方形拼成了一个大正方形,大正方形的边长是5厘米,小正方形的周长是8厘米,那么长方形的宽是多少厘米?六年级的题可以把算式写的完整一些,这样看起来就比较懂 线粒体和叶绿体产生ATP和水的部位的区别 B细胞转化为浆细胞生物膜面积变化内质网 高尔基体 细胞膜面积 为什么不相同比例增大 参加社会实践活动有什么好处?你有什么看法? 七年级下册的第一章整式的运算1整式2整式加减3同底数幂的乘法4幂的乘方与积的乘方5同底数幂的除法6整式的乘法7平方差公式8完全平方公式9整式的除法和1花边有多宽2配方法3公式法4分解因 重点把握哪些知识点? 怎样在电脑上打出根号,幂的符号如2的平方,(2^2除外)和二次根号2计算机高手赐教 叶绿体中有线粒体吗,它自身不是可以产生ATP吗 线性代数: 一:正三棱柱底面边长是3cm,侧棱长都是5cm,则此三棱柱侧面展开图的面积是________平方厘米.二:一个八棱柱的底面边长是3cm,侧棱长之和为56cm求这个八棱柱的侧面积.三:两个完全相同的长方 有丝分裂,一开始间期是不是只有染色单体?染色单体是单一条吗?染色体是两条染色单体相交吗?
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘