分享
 
 
 

一个POP3客户端的C#类

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

一个POP3客户端的C#类

作者: Bill Dean

关键词: C#, VB.NET,.NET, INTERNET

提交: 2002-02-26

更新: 2003-08-06

摘要: 本文描述的是一个实现了标准POP3命令的C#类。

· 下载源文件 - 2 Kb

· 下载演示程序- 5 Kb

· 下载VB.NET版本源文件(Ronny Reinertsen)

简介

读完Agus Kurniawan关于用C#与POP3服务器通讯的文章,我决定如果建立一个POP3客户端的类的话,我将走得更远。我决定为每一个标准的POP3命令实现方法,每一个方法返回一个包含(相应的)POP3服务器响应的字符串,某些情况命令无效,那么这些方法检查这些错误并且返回一个错误信息而不是直接发送命令到服务器。随文的源文件包含类的定义和一个使用该类与POP3邮件服务器通信的控制台演示程序(前面列出)。

类,方法和属性

随附的源代码包含一个类: POP3Client。

POP3Client类包含十个公用方法,其中九个代表标准的POP3命令:

· DELE,

· LIST,

· NOOP,

· PASS,

· QUIT,

· RETR,

· RSET,

· STAT

· and USER

每一个"POPmethods"返回一个字符串,内容为(相应的)POP3服务器响应结果,或者不恰当的命令导致的错误信息。最后一个公用方法:connect用来初始化连结。没有实现可选的POP3命令:APOP, TOP and UIDL。

开始工作后不久,我认识到所有POP3方法应该按以下四个基本步骤实现:

1. 检查该命令载当前的POP状态中是否有效。

2. 如果有效,发送命令到服务器。

3. 读取响应结果。

4. (如果需要)改变POP状态。

我决定用一个叫state的属性来跟踪POP会话的当前状态,数据类型声明为connect_state的枚举类型。你们可以看到这些声明在类的定义的顶部。

public enum connect_state {disc,AUTHORIZATION,TRANSACTION,UPDATE};

...

public connect_state state=connect_state.disc ;

有三个POP状态:AUTHORIZATION、TRANSACTION、UPDATE。(完整的POP3协议定义请参见RFC 1725)state属性在建立任何与POP3服务器的连接之前被设为disc(断开),建立连接后变为AUTHORIZATION。

I also thought it would be useful to store the user name, password, pop server name and error state (i.e.: did an error occur on the last POP3 command), so I add these properties to the class:

我也认为保存用户名、密码、POP3服务器名和错误状态是有用的(例如:判断上一个POP3命令是否发生错误),所以我在类中加入了这些属性:

public string user;

public string pwd;

public string pop;

public bool error;

连接服务器(TcpClient)、发送(NetworkStream)和接收数据(StreamReader)的机制直接取自Agus的代码。我甚至保留了相同的变量名:

// 借用自 Agus Kurniawan的文章:"Retrieve Mail From a POP3 Server Using C#"

// at http://www.codeproject.com/csharp/popapp.asp

private TcpClient Server;

private NetworkStream NetStrm;

private StreamReader RdStrm;

private string Data;

private byte[] szData;

private string CRLF = "\r\n";

在做任何其他工作之前,我们需要建立道服务器的连接以及取得网络流中的信息。这个在connect公用方法中进行。

public string connect()

{

// 初始化连接,这段代码是稍作修改“借” 来的

//来自Agus Kurniawan在www.codeproject.com的文章

// "Retrieve Mail From a POP3 Server Using C#"

// at http://www.codeproject.com/csharp/popapp.asp

// 用110端口创建服务器

Server = new TcpClient(pop,110);

try

{

// 初始化

NetStrm = Server.GetStream();

RdStrm= new StreamReader(Server.GetStream());

//POP会话现在被设为AUTHORIZATION状态

state=connect_state.AUTHORIZATION ;

return(RdStrm.ReadLine ());

}

catch(InvalidOperationException err)

{

return("Error: "+err.ToString());

}

}

注意:只要连接一初始化,会话就进入了AUTHORIZATION状态。

正如前面所提到的,九个POP3方法实质上具有相同的结构。DELE方法的源代码展示出该结构。

public string DELE(int msg_number)

{

string temp;

if (state != connect_state.TRANSACTION )

{

// 只有在POP会话处于TRANSACTION状态时 DELE 命令才为有效

temp="Connection state not = TRANSACTION";

}

else

{

issue_command("DELE " + msg_number.ToString ());

temp=read_single_line_response();

}

return(temp);

}

首先,我们知道DELE POP3命令只在TRANSACTION状态有效,所以如果该类不在这个状态,查看记录在state属性的值,那么返回一个错误信息而不是发送请求到POP3服务器。当处于别的状态时发送DELE命令也不会损伤POP3服务器,只是会产生内部的错误信息而已。如果你宁可让POP3服务器产生状态的错误信息,尽可移出if结构只留下issue_command()调用。一旦确定POP会话处于正确的状态,我们就使用私有方法issue_command发送"DELE"命令到服务器。RFC 1725描述了DELE命令返回一个从服务器发回的单行响应,我们用方法read_single_line_response来读取。两个方法都相当直接明了,不管是向建立连结的服务器写字符还是从建立连结的服务器读取来自于网络流的字符。因为执行完DELE命令后POP会话状态仍为TRANSACTION状态,我们没必要担心要改变state值。state改变的例子请参见源代码的PASS方法。

private void issue_command(string command)

{

// 发送命令到POP服务器,这段代码是稍作修改“借” 来的

// 来自Agus Kurniawan在www.codeproject.com的文章

// "Retrieve Mail From a POP3 Server Using C#"

// http://www.codeproject.com/csharp/popapp.asp

Data= command + CRLF;

szData = System.Text.Encoding.ASCII.GetBytes(Data.ToCharArray());

NetStrm.Write(szData,0,szData.Length);

}

private string read_single_line_response()

{

// 读取POP服务器的响应结果,这段代码是稍作修改“借” 来的

// 来自Agus Kurniawan在www.codeproject.com的文章

// "Retrieve Mail From a POP3 Server Using C#"

// http://www.codeproject.com/csharp/popapp.asp

string temp;

try

{

temp = RdStrm.ReadLine();

was_pop_error(temp);

return(temp);

}

catch(InvalidOperationException err)

{

return("Error in read_single_line_response(): " + err.ToString ()) ;

}

}

注意,在某些情况,有些POP3命令返回多行响应。这里也采用一个名叫read_multi_line_response的方法来处理。我前面已经提到过,我认为显示地判断最后一个POP命令是否正确执行,或者POP3服务器是否返回错误,将是有用的。这里用was_pop_error私有方法来检查。

private void was_pop_error(string response)

{

// 检查POP服务器发出了响应并认为发生了错误

if(response.StartsWith ("-"))

{

// 如果第一个字符是"-"

// 那么pop服务器在执行客户端发过去的最后一个命令时发生错误

error=true;

}

else

{

// 成功

error=false;

}

}

使用示例

POP3协议的细节有点超出本文章的范围。所以如果你想多了解POP3的话,我建议你去RFC 1725,你可以在这里找到。让我们简单的看一下示例程序,以便了解怎样使用这个类:

static void Main(string[] args)

{

POP3Client.POP3client Demo = new POP3Client.POP3client();

Console.WriteLine ("****connecting to server:");

Console.WriteLine (Demo.connect ("your_pop3_server"));

Console.WriteLine ("****Issuing USER");

Console.WriteLine (Demo.USER ("user_id"));

Console.WriteLine ("****Issuing PASS");

Console.WriteLine (Demo.PASS ("password"));

Console.WriteLine ("****Issuing STAT");

Console.WriteLine (Demo.STAT () );

Console.WriteLine ("****Issuing LIST");

Console.WriteLine (Demo.LIST () );

Console.WriteLine ("****Issuing RETR 700...this will cause the POP3 server to gack a "

+ "hairball since there is no message 700");

Console.WriteLine (Demo.RETR (700) );

// 如果没有700消息,将会导致POP3抛出一个错误

Console.WriteLine ("****Issuing RETR 7");

Console.WriteLine (Demo.RETR (7) );

Console.WriteLine ("****Issuing QUIT");

Console.WriteLine (Demo.QUIT ());

Console.ReadLine ();

}

总之,你创建一个POP3Client类的实例,用你的POP3服务器调用connect方法,就可以开始发送命令了。你将需要调用USER和PASS方法以成功登陆服务器,调用其他POP3方法之前必须取得有效的登陆信息。

我希望你们部分人发觉这篇文章是有用的。我也希望收到反馈或建议。

请大家明白该代码没有任何的保证,不管是明示还是暗示。该代码严格的“无保证”提供,仅仅为教育目的。谁使用谁负责。要使用该代码,请允诺使用该代码带来的任何损失与作者和Restek无关。

历史

2003-08-06 —— Ronny Reinertsen好意地把C#版本转为VB.NET

(完)

参看原文:POP3 Client as a C# Class

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有