`
feiliboos
  • 浏览: 673038 次
文章分类
社区版块
存档分类
最新评论

c# 接发邮件

 
阅读更多

本文涉及的内容:
1:自己制作Pop3Helper
信件格式的处理有麻烦
2:使用现成的pop3类
LumiSoft.Net.POP3.Client;
有两种处理方法
3:使用IMAP收邮件
功能似乎更多,比起pop3来。
4:SMTP发送邮件
关于 Mailbox unavailable. The server response was: 5.7.1 Unable to relay for xx 的错误处理

自己写一个POP3的接收程序并不是很简单。主要问题就是如何处理信件的格式。
其处理方法不是太复杂,用一个tcp联接就可以了。
这是代码
public class Pop3Helper
{
string _pop3server;
string _user;
int _port;
string _pwd;

public TcpClient _server;
public NetworkStream _netStream;
public StreamReader _reader;
public string _data;
public byte[] _charData;
public string _CRLF = "/r/n";

private string _log;
public string LogMSG
{
get { return _log; }
}
/// <summary>
///
/// </summary>
/// <param ></param>
/// <param ></param>
/// <param ></param>
/// <param ></param>
public Pop3Helper(string server, int port, string user, string pwd)
{
_pop3server = server;
_port = port;
_user = user;
_pwd = pwd;
}
/// <summary>
/// connect
/// </summary>
public void Connect()
{
//create a tcp connection
_server = new TcpClient(_pop3server, _port);

//prepare
_netStream = _server.GetStream();
_reader = new StreamReader(_server.GetStream());
if (!CheckResult(_reader.ReadLine()))
throw new Exception("Connect Error");

//login
_data = "USER " + this._user + _CRLF;
_charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
_netStream.Write(_charData, 0, _charData.Length);
if (!CheckResult(_reader.ReadLine()))
throw new Exception("User Error");

_data = "PASS " + this._pwd + _CRLF;
_charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
_netStream.Write(_charData, 0, _charData.Length);
if (!CheckResult(_reader.ReadLine()))
throw new Exception("Pass Error");

}
/// <summary>
/// get message Numbers
/// </summary>
/// <returns></returns>
public int GetMailCount()
{
try
{
_data = "STAT" + _CRLF;
_charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
_netStream.Write(_charData, 0, _charData.Length);
string resp = _reader.ReadLine();
string[] tokens = resp.Split(new char[] { ' ' });
return Convert.ToInt32(tokens[1]);
}
catch (Exception ex)
{
return 0;
}
}

public string GetMail(int id)
{
string line;
string content = "";
try
{
//get by id
_data = "RETR " + id + _CRLF;
_charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
_netStream.Write(_charData, 0, _charData.Length);
line = _reader.ReadLine();

if (line[0] != '-')
{
//end with '.'
while (line != ".")
{
line = _reader.ReadLine();
content += line + "/r/n";
}
}


return content;

}

catch (Exception err)
{
Log(err.Message);
return "Error";
}
}
public void DeleteMail(int id)
{
_data = "DELE" + id + _CRLF;
_charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
_netStream.Write(_charData, 0, _charData.Length);
if (!CheckResult(_reader.ReadLine()))
throw new Exception("Delete Error");

}
/// <summary>
/// close connection
/// </summary>
public void Close()
{

_data = "QUIT" + _CRLF;
_charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
_netStream.Write(_charData, 0, _charData.Length);

//close
_netStream.Close();
_reader.Close();
}

private bool CheckResult(string reply)
{
Log(reply);
if (reply.IndexOf("+OK") > -1)
return true;
else
return false;
}
private void Log(string msg)
{
_log += msg + "/r/n";
}
}
。。。。。
但是这种方式的一个问题就是关于解析信件的格式。如果是附件的话,他也直接给出了二进制,不容易使用。
所以,可以使用一个现成的工具:LumiSoft.Net.POP3.Client。这里面已经给写好了实现,用起来也很简单。
这是一个简单的用法(这里使用了两种处理方式,前一种是不建议使用的)
。。
using (POP3_Client pop3 = new POP3_Client())
{
//与Pop3服务器建立连接
pop3.Connect(_popServer, _pop3port,false);
//验证身份
pop3.Authenticate(_user, _pwd, false);

//get all messages
POP3_MessagesInfo infos = pop3.GetMessagesInfo();
foreach (POP3_MessageInfo info in infos)
{
byte[] bytes = pop3.GetMessage(info.MessageNumber);
Mime mime = Mime.Parse(bytes);
HandleMail(mime);
//delete it at last
//pop3.DeleteMessage(info.MessageNumber);
}
//the second way to do it
//for (int i = 0; i < pop3.Messages.Count; i++)
//{
// byte[] bytes = pop3.Messages[i].MessageToByte();
// Mime mime = Mime.Parse(bytes);
// HandleMail(mime);
// //delete it at last
// //pop3.DeleteMessage(pop3.Messages[i].SequenceNumber);
//}。
。。。
取得的邮件可以这要给获得。
#region pop3
//string customer = mime.MainEntity.To.ToAddressListString();//cargo company
//string sender = mime.MainEntity.From.ToAddressListString();//this is customer who send

#endregion
string customer = MailboxesToString(envelope.To);//cargo company
string sender = MailboxesToString(envelope.From);//this is customer who send

。。。
除此之外,它提供的另外一个工具是IMAP,它操作起来更加方便。代码如下:

IMAP_Client clnt = new IMAP_Client();
try
{
clnt.Connect("mail.xx.com", 143, false);
clnt.Authenticate("user", "password");
string[] folders = clnt.GetFolders();//get all types

string folder = "Inbox";
clnt.SelectFolder(folder);


IMAP_SequenceSet sequence_set = new IMAP_SequenceSet();
// All messages
sequence_set.Parse(string.Format("{0}:{1}", 1, clnt.MessagesCount));

IMAP_FetchItem[] fetchItems = clnt.FetchMessages(
sequence_set,
IMAP_FetchItem_Flags.UID | IMAP_FetchItem_Flags.MessageFlags | IMAP_FetchItem_Flags.Size | IMAP_FetchItem_Flags.Envelope,
true, false
);
//int count =0;
foreach (IMAP_FetchItem fetchItem in fetchItems)
{
IMAP_Envelope envelope = fetchItem.Envelope;
//hanldle it, means read and search and reply
try
{
HandleMail(envelope);
//count++;
}
catch (Exception ex)
{
Log("Sys", ex.Message);
}
}
//delete it after hanlde
clnt.DeleteMessages(sequence_set, false);
//disconnect
clnt.Disconnect();

//MessageBox.Show(count.ToString() + " of " + fetchItems .Length+ " Success");
}
catch (Exception x)
{
Log("Sys", x.Message);
//MessageBox.Show(x.Message);
}

。。
上边都是如何收邮件。
关于如何发送邮件是比较简单的。这里提供两种方式。
第一种方式是使用网上的smtp。这种方式必须要提供用户名和密码。这个适合于web应用,使用的smtp也是网上的,我一般使用163的smtp,基本没有问题。
第二种方式是使用本地的smtp。不需要提供密码,用户也可以是不存在的(垃圾邮件是不是就是这么产生的?),但是必要要提供smtp端口号。
第二种方法测试的时候有时候会报错“Mailbox unavailable. The server response was: 5.7.1 Unable to relay for xxx”,查过资料之后(在baidu上没找到,还是google信息多一点),才发现问题原来是IIS里SMTP服务的配置有问题。
这样修改可以解决:到开SMTP属性—>Access页面?Reply Restrictions/ Reply-?Only this Below选项,加上自己的ip:127.0.0.1(允许本机,使用loalhost,如果是允许其他机器,类似设置)
代码如下
public class EMail
{
static public string accountName;
static public string password;
static public string smtpServer;
static public int smtpPort;

/// <summary>
/// need password,username, smtpserver
/// </summary>
/// <param ></param>
/// <param ></param>
/// <param ></param>
static public void SendMail(string sendTo, string subject, string body)
{
//.net smtp
System.Web.Mail.MailMessage mailmsg = new System.Web.Mail.MailMessage();
mailmsg.To = sendTo;
//mailmsg.Cc = cc;
mailmsg.Subject = subject;
mailmsg.Body = body;

//sender here
mailmsg.From = EMail.accountName;
// certify needed
mailmsg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");//1 is to certify
//the user id
mailmsg.Fields.Add(
"http://schemas.microsoft.com/cdo/configuration/sendusername",
EMail.accountName);
//the password
mailmsg.Fields.Add(
"http://schemas.microsoft.com/cdo/configuration/sendpassword",
EMail.password);

System.Web.Mail.SmtpMail.SmtpServer = EMail.smtpServer;
System.Web.Mail.SmtpMail.Send(mailmsg);

}


#region send mail2
/// <summary>
/// need username,smtp,smtp port
/// </summary>
/// <param ></param>
/// <param ></param>
/// <param ></param>
static public void SendMail2(string sendTo, string subject, string body)
{
System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
msg.To.Add(sendTo);
msg.From = new System.Net.Mail.MailAddress(accountName );

msg.Subject = subject;
msg.SubjectEncoding = System.Text.Encoding.UTF8;
msg.Body = body;//
msg.BodyEncoding = System.Text.Encoding.UTF8;
msg.IsBodyHtml = false;
//msg.Priority = MailPriority.High;//

System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
client.Host = smtpServer;
client.Port = smtpPort;
//client.Credentials = new System.Net.NetworkCredential("user@xxx.com", "pass");
client.Send(msg);

}
#endregion

}

Feedback

@寒星星
这里提供的源程序已经够多了,剩下的就是你把他嵌入到自己的程序里.
其实,我也没有demo,都是从实际项目中摘出来的代码而已.
用c#发送邮件,用了很长时间了,也用了不少方法,遇到不少问题.这个随笔算是一个阶段性总结了.
想知道有没有方法处理群发问题?
用for 和用mail.bcc
都有问题,特别是超时问题
LumiSoft.Net.POP3.Client

这个在哪里可以得到??
收邮件好像没这么简单,要把附件弄出来(好像要解码来的)
MailMessage 竟然无法序列化。
这样发送失败的时候想使用MessageQueue 保存都不成。还要自己定义类去保存。

邮件发送失败的后续处理这里有么。
还有邮件的缓存,有时候考虑到服务器的能力可能会缓存一些邮件。空闲的时候再发送。


希望接着写哦。
@Faster
LumiSoft.Net.POP3.Client里面是提供关于附件的解析的.如果自己作pop3,那就真得解码了.
@snoopymin
@暗香浮动

这个问题不属于纯粹的技术问题.
一般情况下,可以通过这样的方式来解决: 设置定时器,不要一次性发送过多邮件.
1:做一个ArrayList,存储发送列表.
2:然后再加一个定时器timer,5分钟执行一次.
3:在timer事件里面来发送邮件,每次发送10个,如果发送失败,就继续保留在list里面,成功则删除.

比较简单的逻辑.
这个随笔只是纯技术的.
剩下的逻辑都是额外的了,比如缓存,比如群发.
群发又有很多问题,比如定时发送,比如如何得知用户阅读情况等等.
LumiSoft其实是一个邮件服务器程序,楼主用的只是最简单的页面POP功能,他还有一个C/S的邮件收发服务器软件,也是开源的,如果配合这个,简直是无敌,不过,国外好多论坛上说这个玩意CPU占用率比较高
@梦想依旧
必须指定.就像访问网页必须要指定哪一个域名(服务器)一样.^_^
@wkcode22
功能确实不错.我用的出了pop3还有imap,不错.
其他功能没有用过,暂时还不需要.
@ithurricane
提供的代码片断已经足够多了。自己根据需要改编一下就行了。
IMAP 协议的接受邮件 你可以给我一份DEMO吗?
关键是 我看不太懂它的帮助,英文 接受后 怎么输出具体内容
例如 标题
我想知道这样用LumiSoft.Net.IMAP.Client的IMAP获取附件信息及邮件内容,希望给出代码,谢谢!!!
分享到:
评论

相关推荐

    C# GSMMODEL 接发短信

    使用控件 通过短信猫 接收、发送短信 使用控件 通过短信猫 接收、发送短信

    基于c#的手机短信接发程序

    c 撑 语言是微软新近推 出的基于 . NE T平台的一种可视化编程工具 , 由于 c 撑 具有强大的功能、 友好的界面和简单易学 ·等特点, 深受广大编程爱好者的青昧。本文是笔者在实际工作中用c 撑 语言开发的一个收发...

    Excel 发邮件抄送给多人

    excel发邮件抄送给多人,各位可以在工作中借鉴,很好的经验!!

    用Google Talk打固定电话和接发语音邮件

    Google Talk如果直接提供打固定电话和接发语音邮件就方便了,语音邮件正在开发中,在不久的将来我们就能看到了,拨打固定电话,Google暂时还顾不上。不过没关系,我们可以通过第三方服务Gtalk2Voip来实现这两个功能...

    邮件接发工具(小巧,绿色,功能齐全,能接-发附件,能显示超邮).rar

    邮件接发工具是一款轻量级、便携式且功能丰富的应用程序,专为处理电子邮件的接收和发送而设计。它的特点是小巧、绿色,意味着它不占用大量系统资源,无需安装即可使用,同时对环境影响小,不会在计算机上留下冗余...

    C#串口收发数据Dome,winfrom串口收发数据测试,vs2010开发

    在本文中,我们将深入探讨如何使用C#进行串口通信,特别是在Windows Forms(Winform)环境中。这个主题基于提供的标题"C#串口收发数据Dome,winfrom串口收发数据测试,vs2010开发"以及描述中提到的源码。串口通信是...

    铁路教学非正常接发列车作业标准PPT课件.pptx

    铁路教学非正常接发列车作业标准PPT课件.pptx

    MQ单项接发消息

    【MQ单项接发消息】是基于消息队列(Message Queue,简称MQ)技术实现的一种通信方式,主要用于在分布式系统中实现可靠的数据传输。MQ是一种中间件,它允许应用程序之间通过发送和接收消息来异步通信,提高了系统的...

    铁路单双线半自动接发列车作业标准.pdf

    铁路单双线半自动接发列车作业标准.pdf铁路单双线半自动接发列车作业标准.pdf铁路单双线半自动接发列车作业标准.pdf铁路单双线半自动接发列车作业标准.pdf铁路单双线半自动接发列车作业标准.pdf

    双线自动闭塞接发列车作业.ppt

    双线自动闭塞接发列车作业.ppt

    非正常接发列车作业模拟

    在铁路运输领域,非正常接发列车作业是指在突发情况如设备故障、自然灾害或其它异常情况下,为了确保行车安全和效率而采取的特殊操作流程。这些情况可能涉及到信号系统失效、线路受损、通信中断等,使得正常的列车...

    接发列车作业程序及技术要求

    3 接发列车作业程序及技术要求 3.1接车(通过)作业(表1) 作业 程序 岗位作业技术要求 说明事项 程序 项目 车站值班员 助理值班员

    IBM System z系列打通丰田汽车电子邮件网络经脉

    信息系统计划事业部技术计划部项目经理 Yoichi Kawase 说:“由于预计业务越来越全球化,因此电子邮件系统必须使用国家标准通过 Internet 接发邮件。尤其是,该系统应当支持 SMTP (Internet 的协议)。此外,丰田还...

    TCP.rar_C# TCP传输_C#的TCP通信_tcp vs2008_tcp数据通信_数据传输

    在文件"TCP网络异步通信_文件接发"中,我们可以预见到会有关于如何在TCP连接上发送和接收文件的示例代码。在C#中,我们可以将文件内容读取为字节数组,然后使用TcpClient的GetStream方法获取网络流,将字节数组写入...

    18年信誉平台接发任务助手

    为方便接发任务开发的一款方便使用的小软件!

    51单片机的接发

    51单片机

    USART—USART1接发_串口_

    USART,即通用同步异步收发传输器(Universal Synchronous Asynchronous Receiver/Transmitter),是微控制器中常用的一种通信接口,常用于设备间的串行通信。在本话题中,我们将深入探讨如何使用USART1来实现数据的...

    行业分类-设备装置-一种接发器.zip

    在IT行业中,接发器是一种重要的通信设备,用于在不同网络之间进行数据传输。这个压缩包文件"行业分类-设备装置-一种接发器.zip"显然聚焦于介绍一种特定的接发器,它可能详细阐述了该设备的技术规格、工作原理、应用...

    行业文档-设计装置-一种接发机.zip

    标题“行业文档-设计装置-一种接发机.zip”表明这是一个关于特定接发机设计的资料包,它可能包含了详细的设计理念、工作原理以及实施步骤等内容。描述中的信息与标题相同,进一步确认了这个压缩包的内容与接发机的...

    2.4G无线接发收电路

    介绍一款工作频率在2.4GHz的接发收电路。

Global site tag (gtag.js) - Google Analytics