二. 代码实现(以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端口,若客户端有连接请求,则Serv erSocketAccept事件会被激活,建立起连接。 procedure TMyForm.ServerSocketAccept(Sender: TObject;  Socket: TCustomWinSoc ket); 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 read y'+crlf); end; ---- 2. 通信 ---- 服务器端收到客户端发来的信息,则会激活ServerSocketClientRead事件,通过S erverSocket的Socket.ReceiveText可以得到信息的内容。 procedure TMyForm.ServerSocketClientRead(Sender: TObject;  Socket: TCustomWi nSocket); 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 pleas e')      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 p lease');     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 comm and yet'+crlf);           end end; ---- 3. 关闭连接    procedure TMyForm.ServerSocketClientDisconnect(Sender: TObject;Socket: TC ustomWinSocket);    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;

解决方案 »

  1.   

    一. 设计思路 ---- 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’命令后服务器才会在断连 前把标志为已删的邮件进行物理删除
      

  2.   

    一. 设计思路 ---- 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’命令后服务器才会在断连 前把标志为已删的邮件进行物理删除