/*
* CopyRight @ taopu软件工作室
* 软件构架师: 陶晓铮
* 代码实现: puha
*
* 功能: 收邮件
* 文件名: Pop3Server.cs
*
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Collections;
namespace ConsoleApplication1
{
public class Pop3Server
{
#region 常量区
private const string COMMAND_DELE = "dele ";
private const string COMMAND_RETR = "retr ";
private const string COMMAND_SEP = " ";
private const string VALUE_USER = "user ";
private const string VALUE_PASS = "pass ";
private const string VALUE_ERR = "-ERR";
private const int DEFUALT_PORT = 110;
private const string DEFUALT_HOST = "localhost";
#endregion
#region 变量区
private string _sHost;
private string _sPassWord;
private string _sUserName;
private int _iPort;
private string _sErrorMsg = "";
private TcpClient _tcpClient;
private NetworkStream ns;
#endregion
#region 属性区
/// <summary>
/// 邮件服务器名称 defual laocalhost
/// </summary>
public string Host
{
set
{
_sHost = value;
}
}
/// <summary>
/// 用户密码
/// </summary>
public string PassWord
{
set
{
_sPassWord = value;
}
}
/// <summary>
/// 用户名
/// </summary>
public string UserName
{
set
{
_sUserName = value;
}
}
/// <summary>
/// 端口,defualt 110
/// </summary>
public int Port
{
set
{
_iPort = value;
}
}
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMsg
{
get
{
return _sErrorMsg;
}
}
#endregion
#region 构造器
/// <summary>
/// 构造器,要求服务器和端口
/// </summary>
/// <param name="sUserName">用户名</param>
/// <param name="sPassWord">密码</param>
/// <param name="sHost">服务器名称</param>
/// <param name="iPort">端口号</param>
public Pop3Server(string sUserName, string sPassWord, string sHost, int iPort)
{
_sUserName = sUserName;
_sPassWord = sPassWord;
_sHost = sHost;
_iPort = iPort;
}
/// <summary>
/// 构造器,使用默认端口号、服务器
/// </summary>
/// <param name="sUserName"></param>
/// <param name="sPassWord"></param>
public Pop3Server(string sUserName, string sPassWord)
: this(sUserName, sPassWord, DEFUALT_HOST, DEFUALT_PORT)
{
//
}
#endregion
#region 可访问方法
/// <summary>
/// 连结到服务器,成功返回真
/// </summary>
/// <returns>成功返回真</returns>
public Boolean DoConnect()
{
try
{
_tcpClient = new TcpClient(_sHost, _iPort);
byte[] outbytes;
string input;
ns = _tcpClient.GetStream();
StreamReader sr = new StreamReader(ns);
sr.ReadLine();
input = VALUE_USER + _sUserName + COMMAND_SEP;
outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
ns.Write(outbytes, 0, outbytes.Length);
sr.ReadLine();
input = VALUE_PASS + _sPassWord + COMMAND_SEP;
outbytes = System.Text.Encoding.ASCII.GetBytes(input.ToCharArray());
ns.Write(outbytes, 0, outbytes.Length);
sr.ReadLine();
return true;
}
catch (SocketException ex)
{
_sErrorMsg = ex.SocketErrorCode.ToString();
return false;
}
//
}
/// <summary>
/// 删除邮件,成功返回真
/// </summary>
/// <param name="iIndex">邮件序号</param>
/// <returns>成功返回真</returns>
public Boolean DoDeleteMail(int iIndex)
{
Byte[] outbytes;
string input;
try
{
input = COMMAND_DELE + iIndex.ToString() + COMMAND_SEP;
outbytes = Encoding.ASCII.GetBytes(input.ToCharArray());
ns.Write(outbytes, 0, outbytes.Length);
}
catch (SocketException ex)
{
_sErrorMsg = ex.SocketErrorCode.ToString();
return false;
}
return true;
}
/// <summary>
/// 按序号取回邮件, 错误时返回null
/// </summary>
/// <param name="iIndex">邮件序号</param>
/// <returns>返回邮件对象 RecMailMsg, 错误时返回null</returns>
public RecMailMsg GetMail(int iIndex)
{
//如果没有连结,连结到服务器
if ((_tcpClient == null) || (!_tcpClient.Connected))
{
if (!DoConnect())
{
return null;
}
}
//取回邮件内容,置入 ArrayList
ArrayList msglines = GetSubMail(iIndex);
if (msglines == null)
{
return null;
}
//测试,保存到本地,查看内容
saveToFile(msglines);
//分解邮件各部份
MailDecode mailDec = new MailDecode(msglines);
RecMailMsg mail = new RecMailMsg();
//取回邮件详细信息
mail.Subj = GetMailSubject(mailDec.mailHeard);
mail.From = GetMailFrom(mailDec.mailHeard);
mail.Date = GetMailDate(mailDec.mailHeard);
//返回邮件对象
return mail;
}
#endregion
#region 内部方法
/// <summary>
/// 测试, 保存邮件内容到本地
/// </summary>
/// <param name="msglines"></param>
private void saveToFile(ArrayList msglines)
{
//合法邮件名测试
string sFileName = "c:/mail";
while (File.Exists(sFileName + ".txt"))
{
sFileName = sFileName + "i";
}
//保存
sFileName = sFileName + ".txt";
using (StreamWriter sw = File.CreateText(sFileName))
{
IEnumerator msgenum = msglines.GetEnumerator();
string line = "";
while (msgenum.MoveNext())
{
line = (string)msgenum.Current;
sw.WriteLine(line);
}
sw.Close();
}
}
/// <summary>
/// 返回指定序号邮件内容,错误返回null
/// </summary>
/// <param name="iIndex">邮件序号</param>
/// <returns>邮件内容,以ArrayList返回, 错误返回null</returns>
private ArrayList GetSubMail(int iIndex)
{
//准备
Byte[] outbytes;
string input;
string line = "";
//在异常保护中送入命令
input = COMMAND_RETR + iIndex.ToString() + COMMAND_SEP;
outbytes = Encoding.ASCII.GetBytes(input.ToCharArray());
StreamReader sr;
try
{
ns.Write(outbytes, 0, outbytes.Length);
sr = new StreamReader(ns);
line = sr.ReadLine();
if (line.StartsWith(VALUE_ERR))
{
_sErrorMsg = line;
return null;
}
}
catch (SocketException ex)
{
_sErrorMsg = ex.SocketErrorCode.ToString();
return null;
}
//置入arrayList
ArrayList msglines = new ArrayList();
do
{
line = sr.ReadLine();
msglines.Add(line);
} while (line != ".");
msglines.RemoveAt(msglines.Count - 1);
return msglines;
}
/// <summary>
/// 得到邮件内容
/// </summary>
/// <param name="msglines">邮件头Array</param>
/// <returns>得到邮件内容</returns>
private string GetMailSubject(ArrayList msglines)
{
string[] tokens;
IEnumerator msgenum = msglines.GetEnumerator();
while (msgenum.MoveNext())
{
string line = (string)msgenum.Current;
if (line.StartsWith("subject:"))
{
tokens = line.Split(new Char[] { ' ' });
return tokens[1].Trim();
}
}
return "None";
}
/// <summary>
/// 得到发件人
/// </summary>
/// <param name="msglines"></param>
/// <returns>发件人地址</returns>
private string GetMailFrom(ArrayList msglines)
{
string[] tokens;
IEnumerator msgenum = msglines.GetEnumerator();
while (msgenum.MoveNext())
{
string line = (string)msgenum.Current;
if (line.StartsWith("from:"))
{
tokens = line.Split(':');
return tokens[1].Trim();
}
}
return "None";
}
/// <summary>
/// 得到发件日期
/// </summary>
/// <param name="msglines"></param>
/// <returns>发件日期</returns>
private string GetMailDate(ArrayList msglines)
{
string[] tokens;
IEnumerator msgenum = msglines.GetEnumerator();
while (msgenum.MoveNext())
{
string line = (string)msgenum.Current;
if (line.StartsWith("date:"))
{
tokens = line.Split(':');
return tokens[1].Trim();
}
}
return "None";
}
#endregion
}
}