DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: sql2003s
今日帖子: 1
在线用户: 3
导航: 论坛 -> 文档资料 斑竹:liumazi,ruralboy  
作者:
男 red987 (red987) ▲△△△△ -
注册会员
2022/10/2 12:36:25
标题:
POP3信箱监视程序 浏览:585
加入我的收藏
楼主: OP3服务器程序通常在TCP端口110提供服务。当客户想要使用服务时,它便与服务器建立一个TCP连接。一旦连接建立,POP3服务器就向客户发送一条欢迎消息。然后客户开始给服务器发送命令,服务器则给出相应的回答。POP3的命令由一个关键词或者关键词加参数组成。每个命令以回车换行(0xD0xA)作为结束标志。对于所有的命令,POP3服务器都会提供一个回答。服务器的回答由一个状态标志加一些附加信息组成。目前使用的两个标志是"+OK"和"-ERR",分别表示客户的命令是否合法。所有的回答也是以回车换行结束。 

   与本文讨论的话题相关的四个POP3命令是USER、PASS、LIST和QUIT。 

   USER 命令 

   格式 USER name 

   其中name是用户在该POP3服务器上的用户标识。客户应该在接到服务器的欢迎消息后或者在上一个USER或者PASS失败之后可以发送此命令。 

   PASS 命令 

   格式 PASS string 

   其中string为该用户的密码。客户在发送了USER命令并且收到了+OK的回答之后方可发送此命令。如果用户名和密码都正确,服务器回答+OK,否则-ERR。 

   LIST 命令 

   格式 LIST 

   如果该用户有邮件,则LIST命令会回答+OK,并列出所有邮件的标识符和大小(每个邮件一行),最后一个仅包含一个句点的行(0xD0xA0x2E)表示整个回答的结束。如果该用户没有邮件,有些服务器会返回-ERR,有些在可能返回一个+OK和一个仅包含一个句点的行。当然,客户必须在PASS命令通过之后客户程序才能给服务器发送LIST命令。 

   QUIT 命令 

   从POP3服务器上退出登录。 

   二、实现相关函数 

   接下来我们按照POP3协议所定义的通信规则来实现一个名叫POP3CheckMail的函数,只要调用此函数,我们就可以检测信箱了。 

   下面的代码是用与Delphi兼容的Pascal语言实现的,我们必须包含WinSock单元,并且在调用下列函数之前初始化好WinSock动态连接库。初始化WinSock动态连接库的代码如下: 

   if WSAStartup($002, wsadata)< > 0 then Halt; 

   POP3CheckMail的原型如下: 

   function POP3CheckMail(E-mail,Password:String;var 

   MailList:TStringList;var ErrorMsg:String):Bool; 

   参数说明: 

   E-mail和Password分别为用户的email信箱名和口令。 

   变量参数MailList用于返回邮件的标识和大小,MailList.Count表示邮件的封数。 

   变量参数ErrorMsg返回出错消息。 

   以下是POP3CheckMail及其它所用到的函数的实现代码。 

二、相关函数 

   Connect_Server函数 

   功能:与指定的主机建立一个TCP连接,返回一个Socket描述符。参数host指定主机的名字,Port指定端口号。 

   function 

   Connect_Server(host:string;Port:integer):integer; 

   var i:integer; 

   p:^LongInt; 

   phe:pHostEnt; 

   sin:sockaddr_in; 

   begin 

   sin.sin_family:=AF_INET; 

   sin.sin_port:=htons(Port); 

   //Get the IP for host, allowing for dotted decimal 

   phe:=gethostbyname(pchar(host)); 

   if phe< > nil 

   then begin 

   p:=Pointer(phe^.h_addr_list^); 

   sin.sin_addr.s_addr:=p^; 

   end 

   else begin 

   i:=inet_addr(PChar(Host)); 

   if i< > -1 then sin.sin_addr.S_addr:=i 

   end; 

   //create a socket 

   Result:=socket(PF_INET,SOCK_STREAM,0); 

   if (Result=INVALID_SOCKET) then Exit; 

   //connect to server 

   if Connect(Result,sin,sizeof(sin))=SOCKET_ERROR 

   then 

   begin {Error handling} 

   end; 

   end; 

三、其他相关函数 

   Write_Socket函数 

   功能:向Socket写入一个字符串。 

   function Write_Socket(sockfd:Integer; const s:string):Integer; 

   begin 

   result:=Winsock.Send(sockfd,pointer(s)^,Length(s),0) 

   end; 

   Socket_Readline函数 

   功能:从Socket上读取一行。 

   function Socket_Readline(sockfd:Integer):String; 

   //Read until #10 

   var S:String; buf:array[0..1]of Char; 

   n:Cardinal; 

   begin 

   buf[0]:=#0;buf[1]:=#0; S:=‘'; 

   n:=recv(sockfd,Buf,1,0); 

   while n> 0 do begin 

   buf[1]:=#0; 

   S:=S+buf; 

   if (buf[0]=#10) then Break; 

   n:=recv(sockfd, buf, 1, 0); 

   end; 

   Result:=Trim(S); 

   end; 

四、重要的Pop3函数 

   Pop3Response函数 

   功能:读取POP3服务器的一行返回信息,如果是"+OK"则函数返回TURE,如果是"-ERR"则返回FALSE。 

   function Pop3Response(Sockfd:Integer):Bool; 

   var S: string; 

   begin 

   S:=socket_readline(sockfd); 

   if copy(s,1,3)=‘+OK' then Result:=True 

   else {if copy(s,1,4)=‘-ERR' then }Result:=False; 

   end; 

   POP3CheckMail函数 

   功能:检测名字为email的信箱,如果有新邮件,则通过变量参数MailList将每一封邮件的大小返回。 

   function POP3CheckMail(E-mail,Password:String; 

   var MailList:TStringList;var ErrorMsg:String):Bool; 

   var sockfd,i:integer; 

   S, Host, User:String; 

   begin 

   Result:=False; ErrorMsg:=‘'; 

   if MailList=nil then Exit; 

   S:=Trim(E-mail); 

   i:=Pos(‘@',E-mail); 

   User:=Trim(Copy(S,1,i-1)); 

   Host:=Trim(Copy(S,i+1,Length(E-mail)-i)); 

   MailList.Clear; 

   if (user=‘')or(host=‘') 

   then begin ErrorMsg:=‘Invalid email address.'; 

   exit; 

   end; 

   if (Host[1]=‘[')and (Host[Length(host)]=‘]') 

   then 

   begin Host[1]:=‘ ';Host[Length(host)]:=#0; 

   end; 

   Host:=Trim(host); 

   sockfd:=Connect_Server(Host,110); 

   if not Pop3Response(sockfd) 

   then 

   begin ErrorMsg:=‘Cannot connect to server'; 

   exit; 

   end; 

   Write_Socket(sockfd,‘USER '+User+#13#10); 

   IF NOT POP3Response(sockfd) then 

   begin 

   ErrorMsg:=‘USER failed'; 

   Exit; 

   end; 

   Write_Socket(sockfd,‘PASS '+Password+#13#10); 

   IF NOT POP3Response(sockfd) 

   then 

   begin 

   ErrorMsg:=‘PASS failed'; 

   Exit; 

   end; 

   Write_Socket(sockfd,‘LIST'#13#10); 

   POP3Response(sockfd); 

   while true do begin 

   s:=Socket_readline(sockfd); 

   if s=‘.' then BREAK; 

   MailList.Add(S); 

   end; 

   Write_Socket(sockfd,‘QUIT'#13#10); 

   Closesocket(sockfd); 

   Result:=True; 

   end; 

五、邮件的检测 

   下面我们来看一个使用POP3CheckMail函数的简单示例。 

   var MailList:TstringList; 

   ErrorMsg:String; 

   ... 

   MailList:=TstringList.Create; 

   POP3CheckMail(‘simon_liu@263.net', ‘ 

   mypassword', MailList, ErrorMsg); 

   If MailList.Count> 0 then 

   MessageBox(0, Pchar(‘You have '+ 

   IntToStr(MailList.Count)+ ‘ new messages!'), ‘New 

   Message!', MB_ICONINFORMATION) 

   Else if ErrorMsg=‘' then MessageBox(0, ‘No message!', ‘',0) 

   Else MessageBox(0, Pchar(ErrorMsg), ‘Error', 0); 

   MailList.Free; 

   如果你仔细阅读了POP3CheckMail函数的实现代码,你会发现此函数除了可以获取邮件的封数之外,还可以获得每一封邮件的大小。你可以通过POP3CheckMail函数的变量参数MailList的Strings数组来获取邮件的大小。 

   实现了POP3CheckMail函数,再在此基础上编写一个POP3信箱的监视程序就变得很简单了。你可以通过一个定时器来定期地调用POP3CheckMail函数,这样你就可以监视某个email信箱了。假若你想要同时监视多个email信箱,只要为每一个信箱创建一个线程并且在线程中定期调用POP3CheckMail函数即可。你的程序中如果没有使用Delphi的控件,那么一个完整的信箱监视程序可能只有60K左右。
----------------------------------------------
-
作者:
男 luckyrandom (luckyrandom) ★☆☆☆☆ -
普通会员
2022/10/2 22:24:52
1楼: 正准备做个检测邮件的小工具。。支持
----------------------------------------------
SQL SERVER DBA QQ:315054403 曾经的Delphier  缘在上海
作者:
男 pcplayer (pcplayer) ★☆☆☆☆ -
普通会员
2022/10/3 1:29:28
2楼: POP3 以及发送邮件的 SMTP ,直接用 Indy 的控件,因为 Indy 提供了 Demo 程序,很容易就学会该怎么用了。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行33.20313毫秒 RSS