一.前言
Visual C#作为一门新兴的编程语言,具有许多其它语言无法比拟的优点。它既有VB的快速简洁,同时又不失C++的高效性能,而且作为一门基于组件编程的语言,它在组件编程方面有着相当强大和完善的功能。本文笔者就通过运用Visual C#编写一个Pop3邮件接收组件向大家介绍如何用Visual C#进行组件编程以及编程过程中的一些方法和技巧,最后还给出了一个对该Pop3组件进行测试的Windows Forms程序。
二.基本原理
要完成一个Pop3组件,就要完成对该组件的属性(Property)、方法(Method)和事件(Event)等的设计。属性是一个组件的重要特征,一个组件一般有多项属性。我们可以通过get和set取得和设置各个属性的值。完成了各个属性的设置,我们可以通过该组件的各种方法进行相应的操作。而事件则是在某些特定的消息下触发的。在C#中,我们用代表(delegate)进行事件的声明。
在该Pop3组件中,我们为其添加了主机名(Host)、端口号(Port)、用户名(UserName)、密码(PassWord)、邮件数目(NumOfMails)、邮件大小(TotalSize)等属性,通过ReceiveMessage()和ReceiveMessageAsync()方法完成与服务器的连接、通讯和结束会话等功能,在调用了该方法后,我们就可以从邮件数目和邮件大小等属性中获得邮箱中的相关信息,进而运用该组件就可以轻松地开发出诸如邮件信史之类的程序了。同时,该组件中还包含了一个OnMailReceived()事件,该事件在完成了邮件的接收后被触发。
在组件的设计过程中,与主机的连接通讯是该组件的核心部分,所以我们不妨专门设计一个与主机的连接类-Pop3Connection类,该类是主要运用了TcpClient类的对象,和主机建立基于TCP/IP网络协议的连接。在完成连接后,可以和主机进行通讯。完成通讯后,则关闭与主机的连接。在大致介绍了实现原理后,下面就是具体的实现方法了。
三.实现方法
首先,打开VS.net,新建一个Visual C#的项目:在项目类型中选择"Visual C#项目",在模板中选择"类库",不妨将该项目命名为"Pop3Com"(这样,由该项目生成的组件的命名空间就为Pop3Com了),图示如下:
1.Pop3Connection类:
这样,项目向导就完成了,接着我们将原来的Class1.cs改名为Pop3.cs,同时添加一个类Pop3Connection(文件名不妨为Pop3Connection.cs)。
如上所述,Pop3Connection类完成了与主机的连接、通讯和关闭连接等功能,所以我们必须调用.Net框架中进行网络通讯的类库,在此我们运用的是TcpClient类的对象作为网络连接的客户端。同时,在与主机的通讯过程中必然少不了对于输入输出流的控制。于是,我们在设计该类的时候,首先得添加如下命名空间:
using System.IO; using System.Net.Sockets; Pop3Connection类的成员变量包括以下几个: private TcpClient socket; private StreamReader reader; private StreamWriter writer; private bool connected; |
其中,bool类型的connected变量用于判断是否与主机取得了连接,它是该类的一个属性,对其操作如下:
public bool Connected { get{return connected;} } Pop3Connection类的主要方法包含以下几个: internal void Open(string host, int port) { if(host == null || host.Trim().Length == 0 || port <= 0) { throw new System.ArgumentException("Invalid Argument found."); } socket.Connect(host, port); reader = new StreamReader(socket.GetStream(), System.Text.Encoding.ASCII); writer = new StreamWriter(socket.GetStream(), System.Text.Encoding.ASCII); connected = true; }
internal void SendCommand(string cmd) { writer.WriteLine(cmd); writer.Flush(); }
internal void GetReply(out string reply, out int code) { reply = reader.ReadLine(); code = reply == null ? -1 : Int32.Parse(reply.Substring(0, 3)); }
internal void Close() { reader.Close(); writer.Flush(); writer.Close(); reader = null; writer = null; socket.Close(); connected = false; }
|
根据这些方法的名称,我们不难知道它们的作用。第一个方法Open()就是根据主机名和端口号取得和服务器的连接。一旦连接成功,就通过TcpClient类的对象获取网络通讯流并新建一个StreamReader对象和一个StreamWriter对象。不言而喻,这两个对象的作用是控制网络通讯的输出和输入。最后,还要将connected的属性设置为true。第二个方法SendCommand()就是在上面的StreamWriter类的对象writer的基础上往网络套接字中输入信息。而第三个方法GetReply()则正好相反,它是用来从网络套接字中获取信息的。最后一个方法Close()的作用则是关闭输出、输入流的对象,然后调用TcpClient类的对象Close()方法并将connected属性设置为false,从而关闭连接,结束会话。
2.Pop3类:
这样,我们就完成了Pop3Connection类的设计和编码工作,也就完成了整个组件最关键的部分。接下来,我们就在该类的基础上设计Pop3类。Pop3类包含了邮件通讯所必须的基本属性、方法和事件。
首先,我们来设计其中的属性。该类应该包括主机名、端口号、用户名、密码、邮件数量、邮件总体积、邮件内容和状态信息等属性。其中前四个属性是可读又可写的,后四个属性是只可读的。具体的设置如下:
/// /// 主机名 /// public string Host { get {return host;} set { if(value == null || value.Trim().Length == 0) { throw new ArgumentException("Invalid host name."); } host = value; } }
/// /// 端口号 /// public int Port { get {return port;} set { if(value <= 0) { throw new ArgumentException("Invalid port."); } port = value; } }
/// /// 用户名 /// public string UserName { get {return username;} set { if(value == null || value.Trim().Length == 0) { throw new ArgumentException("Invalid user name."); } username = value; } }
/// /// 密码 /// public string PassWord { get {return password;} set { if(value == null) { throw new ArgumentException("Invalid password."); } password = value; } }
/// /// 邮件数量 /// public int NumOfMails { get {return numofmails;} }
/// /// 邮件总体积 /// public double TotalSize { get {return totalsize;} }
/// /// 邮件内容 /// public string Body { get {return body;} }
/// /// 状态信息 /// public string Status { get {return status;} } |
完成了该类的属性设计,我们接下来就完成该类的方法设计。该类主要的方法就一个ReceiveMessage(),顾名思义就是接收邮件信息的意思。在这个方法中,我们运用了上面的Pop3Connection类的对象。通过这个对象,我们就可以更加方便的进行网络通讯的操作。不过,在具体介绍这个方法的实现以前,我先得向大家介绍一下邮件接收的基本原理。