您的位置:首页 > 编程语言 > C#

Visual C#实现自定义组件的设计2

2007-05-14 16:39 253 查看
 其基本原理如下:

  一开始便是客户端与服务器的连接。不过,在客户端连接到服务器之前,注意把端口设为POP3协议默认的110号。

  客户端连接服务器成功后,服务器会返回以下信息:

   +OK……

  字符+OK是POP3协议的返回信息。它的回应信息不像SMTP协议那样用丰富多变的数字表示,只有两个:+OK或者-ERR。其中,+OK表示连接成功,而-ERR则表示连接失败。

  接下来,客户端输入USER <用户名>

  该命令告诉服务器你的用户名。注意,有些服务器会区分大小写字母的。

  服务器返回+OK后,客户端输入PASS <口令>

  服务器返回+OK后,还返回一些邮箱的统计信息,比如:+OK 1 message(s) [1304 byte(s)]
不同的服务器返回的信息格式不太一样,所以我们可以用STAT命令来查看邮箱的情况。STAT命令的回应中有两个数字,分别表示邮件的数量和邮件的大小。

  如果信箱里有信,就可以用RETR命令来获取邮件的正文。RETR命令的格式为:

   RETR <邮件编号>

  如果返回结果第一行是+OK信息,则表示成功。第二行起便是邮件的正文。最后一行和SMTP协议一样,是一个单独的英文句号,表示邮件的结尾部分。

  把邮件存储起来后要用DELE命令删除邮箱中的邮件,否则原有的邮件会继续保留在服务器上,一旦邮件一多,你的邮箱就爆了。DELE命令的格式为:

   DELE <邮件编号>

  如果删错了,可以用RSET命令来恢复所有已被删除的邮件。条件是你还没有退出,一旦退出,那就一切Bye Bye了。全部完成以后,输入QUIT命令就可以退出POP3服务器了。

  在了解了邮件接收的基本原理的基础上,我就向大家介绍ReceiveMessage()方法的具体实现:

///
/// 接收邮件信息
///
public void ReceiveMessage()
{
 // 避免线程冲突
 lock(this)
 {
  // 设置初始连接
  con = new Pop3Connection();
  if(port <= 0) port = 110;
   con.Open(host, port);

  StringBuilder buf = new StringBuilder();
  string response;
  int code;

   // 获取欢迎信息
  con.GetReply(out response, out code);
  status += response;

  //登录服务器过程
  buf.Append("USER");
  buf.Append(username);
  buf.Append(CRLF);
  con.SendCommand(buf.ToString());
  con.GetReply(out response, out code);
  status += response;
 
  buf.Length = 0;
  buf.Append("PASS");
  buf.Append(password);
  buf.Append(CRLF);
  con.SendCommand(buf.ToString());
  con.GetReply(out response, out code);
  status += response;

  //向服务器发送STAT命令,从而取得邮箱的相关信息:邮件数量和大小
  buf.Length = 0;
  buf.Append("STAT");
  buf.Append(CRLF);
  con.SendCommand(buf.ToString());
  con.GetReply(out response, out code);
  status += response;

  //将总邮件数和邮件大小分离
  string[] TotalStat = response.Split(new char[] {' '});
  numofmails = Int32.Parse(TotalStat[1]);
  totalsize = (double)Int32.Parse(TotalStat[2]);

  for( int x = 0; x < numofmails; ++x)
  {
   //根据邮件编号从服务器获得相应邮件
   buf.Length = 0;
   buf.Append("RETR");
   buf.Append(x.ToString());
   buf.Append(CRLF);
   con.SendCommand(buf.ToString());
   con.GetReply(out response, out code);

   if(response[0]!='-')
   {
    //不断地读取邮件内容,只到结束标志:英文句号
    while(response!=".")
    {
     body += response;
     con.GetReply(out response, out code);
    }
   }
   else
    status += response;
  }
  //向服务器发送QUIT命令从而结束和POP3服务器的会话
  buf.Length = 0;
  buf.Append("QUIT");
  buf.Append(CRLF);
  con.SendCommand(buf.ToString());
  con.GetReply(out response, out code);
  status += response;

  con.Close();

  // 邮件接收成功后触发的事件
  if(OnMailReceived != null)
  {
   OnMailReceived();
  }
 }
}
  根据邮件接收的基本原理和代码中的注释,我想读者应该不难读懂上面的代码。不过下面几点仍得说明:其中的CRLF为"/r/n",它的作用是在每个命令后面加上一个换行符。另外,在该方法的一开始处有一句:lock(this),它的作用是避免线程冲突。考虑到接收邮件的过程比较漫长而且占用的资源较多,所以在设计的时候我用到了多线程(有关多线程的资料读者可参考相关的书籍或文章,此处不再赘述)。在实际的程序中,上面的方法其实被另一个方法ReceiveMessageAsync()作为一个单独的线程调用。方法如下:

///
/// 通过一个独立的线程接收邮件
///
public void ReceiveMessageAsync()
{
 new Thread(new ThreadStart(ReceiveMessage)).Start();
}
  最后,在ReceiveMessge()方法的末尾处,它调用了事件处理函数OnMailReceived()。在C#中,事件的声明是用代表完成的,首先我们在Pop3类的开始处进行声明如下:

public delegate void MailReceivedDelegate();
  接着,就进行事件的声明:

public event MailReceivedDelegate OnMailReceived;
  这样,只要在应用程序中调用了OnMailReceived()事件,在邮件接收成功后,OnMailReceived()事件就会被触发。

  到此为止,我们已经完成了核心类-Pop3类的属性、方法和事件的设计,这样整个组件也就完成了(按Ctrl+Shift+B就可以生成解决方案)。不过,由于是组件,所以不可以直接运行,我们必须做一个测试程序来测试之。下面我就用该组件做了一个简单的邮件信史,它可以向用户报告邮箱中的新邮件数目。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: