Email服务器之间的通讯协议是怎样的 (300分)

  • 主题发起人 主题发起人 MrMengyi
  • 开始时间 开始时间
M

MrMengyi

Unregistered / Unconfirmed
GUEST, unregistred user!
如题
我想知道FoxMail怎么做特快专递的

还有,Email服务器有没有统一的程序接口
如 可以编程增加用户
 
应该是通过DNS,直接查找对方计算机,然后讲信息发送到服务器上吧。
不太懂,讲刚刚收集的资料贴上:
所有STMP命令:
HELO <SP> <domain> <CRLF>
MAIL <SP> FROM:<reverse-path> <CRLF>
RCPT <SP> TO:<forward-path> <CRLF>
DATA <CRLF>
RSET <CRLF>
SEND <SP> FROM:<reverse-path> <CRLF>
SOML <SP> FROM:<reverse-path> <CRLF>
SAML <SP> FROM:<reverse-path> <CRLF>
VRFY <SP> <string> <CRLF>
EXPN <SP> <string> <CRLF>
HELP [<SP> <string>] <CRLF>
NOOP <CRLF>
QUIT <CRLF>
TURN <CRLF>
 
smtp
esmtp
pops
验证auth
我都已经看了
您的资料对我的问题帮助不是很大
我要的是email服务器之间的协议
 
会有吗?
和普通发送接收不一样吗?我真的不是特别懂。[:)]
 
smtp,pop3是c/s结构的
服务器之间的传递我就很不清楚了
 
今天在论坛上找到两片文章,关于如何编写SMTP邮件服务器的,是否需要?
 
请您给出地址
谢谢
 
贴出来吧:
如何编写SMTP邮件服务器

来源:www.chinaasp.com

许多时候,我想不通为什么不能直接将信件送到对方(POP或IMAP)服务器上,
为什么非要通过一个莫名其妙的SMTP邮件服务器转交一次,实在不服气,如果使
用UNIX,这个问题就很好解决,用sendmail就能完成递送任务,但在Windows下
呢?同样的,一定也有办法饶开SMTP Server直接递送到对方的远程邮局服务器
上,难得住别人,难得住我们程序员吗?分析相关协议(RFC2645,RFC821,
RFC1846,RFC1939,RFC1725,RFC1730-RFC1733 etc.),我们会知道要完成直接递
送其实相当简单。
首先我们看一下Email的递送过程:
Email(Encode) -> a SMTP Relay Server -> Remote SMTP Server(远程邮局)。
非常简单,邮件编码后被递送到一个SMTP转交服务器上,该服务器对信件分检
(到同一邮局的被放在一起)后,根据优先级以及信件的先后次序被发送到远程
邮局的SMTP服务器上。换句话说,只要我们知道了SMTP转交服务器是如何确定远
程邮局SMTP服务器的地址的,就可以轻松地将饶开SMTP Relay Server直接递送到
远程邮局服务器。
SMTP Relay Server是如何确定远程邮局服务器的地址的呢?如果你熟悉域名解析,
就知道是怎么回事了,我们知道电子邮件的地址由两部分构成postbox@address.com,
邮箱(postbox)和地址(address.com),给域名服务器发送指令查询"address.com”
的远程邮局服务器的地址即可找到远程邮局SMTP服务器的IP 地址,该指令查询是被
称作MX(Mail Exchange)邮件交换服务器的地址查询。远程邮局SMTP服务器的地址可
能不止一个,这时,你可根据信件优先级的不同,将对应优先级的信件发到对应地址
的远程邮局SMTP服务器,当然,你也可以不管三七二十一,随便选一个SMTP服务器发
送,见后附“域名解析结果样例”。简单吧。这下,自己编写一个SMTP Server不难了
吧!

问题:头ID是个麻烦的事,有时会产生Invalid Head ID 5811的错误。

附:域名解析结果样例

Answer List

Resource name is : sina.com
Type is : MX Class is : IN
MX Priority : 10 MX Server : mailcn.sina.com

Resource name is : sina.com
Type is : MX Class is : IN
MX Priority : 15 MX Server : mail.sina.com.cn


Authority List

Resource name is : sina.com
Type is : NS Class is : IN
Domain name is : resolver.sina.com

Resource name is : sina.com
Type is : NS Class is : IN
Domain name is : ns2.sina.com


Additional Response List

Resource name is : mailcn.sina.com
Type is : A Class is : IN
IP Address is : 202.106.184.233

Resource name is : mail.sina.com.cn
Type is : A Class is : IN
IP Address is : 202.106.187.150

Resource name is : resolver.sina.com
Type is : A Class is : IN
IP Address is : 206.204.114.135

Resource name is : ns2.sina.com
Type is : A Class is : IN
IP Address is : 209.133.24.135
 
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 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服务器吧!
 
还没看呢,好像里面就涉及两个smtp服务器之间的信息交换[8D][:D][:)]
 
没错,呵呵,第一片就是。
唉,只会收集,不会欣赏。
没想到歪打正着了[:(]
 
谢谢你了
我看过后就发分

我太。。。,竟然忘记了chinaasp站
呵呵
再次感谢
 
其实,我也应该谢谢你,不是你,我恐怕还要过几天甚至一个月后才会仔细看这片文章。
唉,知道收集资料,也要知道用资料呀。[:(]
 
chinaasp访问不到
您的帖子看不太明白
我会另开主题讨论
这里分数照给
SMTP Relay Server的RFC我还没看懂
这个是关键呀
 
接受答案了.
 
后退
顶部