如何实现把邮件直接发送到对方邮箱,就想foxmail的‘特快专递’功能?300分,不够再加!(300分)

  • 主题发起人 城里的月饼
  • 开始时间

城里的月饼

Unregistered / Unconfirmed
GUEST, unregistred user!
同标题,最好有范例
 
应该是自己作为SMTP服务器了,使用SMTP服务器间的传输,将信件直接发送到对方服务器。
 
我正好有一个Delphi版的“特快专递”的源代码,而且我已测试成功,
不过我现在出差在外,而源代码在我的机子 
 
Teny:如果您回来后,且您的源码在不涉及到保密或知识产权保护的问题的情况下,能否发给我,让我研究研究?,谢谢你!
我的email是 :zyplay@sohu.com;我就是对如何建立stmp服务器很挠头!
 
请给我也发一份,谢谢Teny!
pschen@21cn.com
 
千万记得给我一份:datm@21cn.com
先谢过。
 
这个先贴出来(转载),大家解解馋,呵呵。不过好像已经贴过一次了。[:)]
Email 服务器的简单实现
湖南艾邦信息技术有限公司
李岳梅
---- 贵刊1999年7月26日《编程技巧》栏目刊登的《监视POP3信箱》一文介绍了直接调用WinSock
函数来进行POP3网络通信从而监视有无新邮件的方法。但我们知道从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 ClientSocketdo
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服务器吧!
 
是自已虚拟的吗。mailto:xf-wangyi@163.com
 
To Teny:
谢谢,也请给我来一份 redone@kmmx.net ^_^
 
去这里下载SMTP Server Componennts 源程序,所带demo就是一个能够直接发送邮件的例子:
http//sourceforge.net/projects/smtpsvr
支持: kylix!
我也写过一篇关于如何直发邮件的文章的,就不重复啦!
 
TO Teny:
Please mail to me.
E-MAIL:kingdeezj@sina.com
Thanks.
 
呵呵,到 Indy (Delphi6里面的空间组)主页上下载他的demos, 你就可以看到 SMTPRelay 这个例子
很简单的直接发送email的例子,大家试试吧
enjoy
 
是不是自己设置成服务器,那就要在计算机上安装相关的软件了.
 
不用,只要设置好 DNS 就可以了,呵呵,
 
TO:riceball
你给的链接连不上!有没有其它的办法?
 
delphi自带的例程里就有POP3收信程序。如发信,我做了一个小软,速度快,好用。:)
也算是我做广告吧。
下载地址:
http://www.csdn.net/cnshare/soft/openfile.asp?kind=1&id=7864
 
实现foxmail的‘特快专递’功能,请看这里
http://www.nevrona.com/indy/
Delphi6 and Kylix 原生代码支持,哈哈,下载它的demos,里面就有例子 SMTPRelay
重要一点,it is FREE and POWERFUL
 
我的研究成果告诉我 其实原理是这样的:
比如:datm@21cn.com
你就需要得到 DNS的MX解析@21cn.com是什么?
然后就是很简单的用smtp控件发送信件到@21cn.com。
我已经试验成功过了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
顶部