C和C#两种方式实现简单的邮件发送
内容为通过两种方式发送邮件--1.C语言发送邮件 2.C#发送邮件
一,C语言进行邮件的发送
C语言发送邮件的步骤的简单解析:
1.创建TCP连接 socket()
2.连接到邮箱服务器SOCKADDR_IN,connect()
3.邮箱用户和密码认证登录"EHLO smtp.163.com\r\n" → "AUTHLOGIN\r\n"
4.发送邮件主题内容
a.发送 "MAIL FROM:<"邮件的发送方地址">\r\n"//
b.发送 "RCPT TO:<"邮件接收方的地址">\r\n"
c.发送"DATA\r\n"
d.发送邮件头(From,To,Subject,Date等),邮件体(邮件体可为空)
e.添加附件内容(可以添加多个,附件也可以不添加)
5.退出登录发送"QUIT\r\n"
6.关闭TCP连接closesocket(connection);
C语言关键代码如下:
//创建TCP连接
if ((connection = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
returnINVALID_SOCKET;
}
//连接到邮箱服务器
void ConnectToServer(SOCKETconnection,const char *serverName)
{
//设置SockAddr_In地址结构
SOCKADDR_INserAddr;
serAddr.sin_family= AF_INET;
serAddr.sin_port= htons(SMTP_PORT);
//来自CAsysSocket::Connect()
serAddr.sin_addr.s_addr= inet_addr(serverName);
if(serAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(serverName);
if (lphost != NULL)
serAddr.sin_addr.s_addr =((LPIN_ADDR)lphost->h_addr)->S_un.S_addr;
else
return;
}
//连接服务器
connect(connection,(SOCKADDR *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) return;
}
//认证登录
//认证登录
BOOL AuthLogin(SOCKET connection, constchar *serverName,const char *userAccount, const char *password)
{
//发送EHLO%SMTP-ServerName% 说明:HELO 是不带身份验证的,而 EHLO 是带身份验证
charszHello[PARA_BUF] = { 0 };
sprintf(szHello,"EHLO %s\r\n", serverName); //"EHLO%s\r\n" if (!send_rev(connection,szHello, GENERIC_SUCCESS))
return FALSE;
//发送AUTHLOGIN
if(!send_rev(connection, "AUTH LOGIN\r\n", AUTHLOGIN_SUCCESS)) // "AUTH LOGIN\r\n"
return FALSE;
//发送经过Base64编码的用户账号
charszAccount[100]={0};
base64_encode(userAccount,strlen(userAccount), &szAccount); //base64编码
strcat(szAccount,"\r\n");
if(!send_rev(connection, szAccount, AUTHLOGIN_SUCCESS)) //账号
return FALSE;
//发送经过Base64编码的密码
charszPassword[100]={0};
base64_encode(password,strlen(password), &szPassword);
strcat(szPassword,"\r\n");
if(!send_rev(connection, szPassword, AUTH_SUCCESS)) //密码
return FALSE;
return TRUE;
}
//发送邮件(包含了用户的退出操作QUIT)
//发送邮件
BOOL SendMail(SOCKET connection,const char*from,
const char *to,
const char *subject,
const char*body,
const char*userName,
const char*filePath)
{
charszFrom[PARA_BUF] = { 0 };
charszTo[PARA_BUF] = { 0 };
charszSubject[PARA_BUF] = { 0 };
charszBodyHead[PARA_BUF * 10] = { 0 };
charszBody[PARA_BUF * 20] = { 0 };
charszDateTime[PARA_BUF] = { 0 };
char*szContent=NULL;
//邮件的内容,包括正文文本信息,附件内容信息等
if(!chars_malloc(&szContent, MAX_FILE_SIZE*4/3 + M ) )
{
return FALSE;
}
//发送Header中的MailFrom
sprintf(szFrom,"MAIL FROM:<%s>\r\n", from); // MAIL FROM:<%s>\r\n
if(!send_rev(connection, szFrom, GENERIC_SUCCESS) )
return FALSE;
//发送Header中RCPT TO
sprintf(szTo,"RCPT TO:<%s>\r\n", to); // RCPT TO:<%s>\r\n
if(!send_rev(connection, szTo, GENERIC_SUCCESS))
return FALSE;
//发送DATA\r\n
if(!send_rev(connection, "DATA\r\n", DATA_SUCCESS)) // DATA\r\n
return FALSE;
//进行 Body 处理
sprintf(szFrom,"FROM:%s<%s>\r\n", userName, from); //content
sprintf(szTo,"TO:<%s>\r\n", to);
time_t ltime =time(NULL);
_tzset();
sprintf(szDateTime,"Date:%s", ctime(<ime));
sprintf(szSubject,"Subject:%s\r\n", subject);
sprintf(szBodyHead,"X_Mailer:ntSmtp[ch]\r\n", subject);
strcat(szBodyHead,"MIME_Version:1.0\r\n");
strcat(szBodyHead,"Content- type:multipart/mixed;Boundary=ntSmtp\r\n\r\n");
strcat(szBodyHead,"--ntSmtp\r\n");
strcat(szBodyHead,"Content-type:text/plain;Charset=gb2312\r\n");
strcat(szBodyHead,"Content_Transfer-Encoding:8bit\r\n\r\n");
sprintf(szBody,"%s\r\n\r\n", body);
//连接成content的各部分内容
strcat(szContent,szFrom);
strcat(szContent,szTo);
strcat(szContent,szDateTime);
strcat(szContent,szSubject);
strcat(szContent,szBodyHead);
strcat(szContent,szBody);
if (filePath !=NULL)
{
//将附件内容添加到szContent
AppendAttachment( &szContent, filePath);
//AppendAttachment(&szContent, filePath);
}
//添加结束标记
strcat(szContent,"\r\n.\r\n"); // \r\n.\r\n
//发送Content
if (!send_rev(connection, szContent, GENERIC_SUCCESS) )
return FALSE;
//发送Quit,退出登录
if(!send_rev(connection, "QUIT\r\n", QUIT_SUCCESS) ) //"QUIT\r\n"
return FALSE;
free(szContent);
return TRUE;
}
二,C#进行邮件的发送
通过C#进行邮件的发送,不需要C语言那样必须把握住连接通信过程中的诸多细节,如果进行简单的邮件发送,只需要使用到两个类,一个是MailMessage类,该类定义了一封完整邮件多需要的信息(包括邮件的发送方,接收方,主题,正文内容,附件等信息),另一个是SmtpClient类,该类是用于服务器端的操作,通过该类的对象,你就可以设置邮箱服务器的地址(例如:smtp.163.com),邮箱的登录账号与密码等,最终通过该类的对象便可以将MailMessage的信息发送到指定的邮箱了.
C#发送邮件的步骤的简单解析:
1.创建MailMessage对象,设置MailMessage的相关成员数据; 包括From,To,Subject,Body,Attachments等信息.
2.创建服务器端对象SmtpClient,设置服务器,邮箱账号,密码.
3.通过SmtpClient对象,将MailMessage邮件信息发送出去; 可以进行普通的发送以及异步发送(不阻塞线程).
C#关键代码如下:
//异步发送邮件
//发送按钮
private void btn_Send_Click(object sender,EventArgs e)
{
//创建MailMessage对象
MailAddress from = new MailAddress("ntsmtp@163.com");
MailAddress to = new MailAddress("miaosha5s@sohu.com");
MailMessage mailMessage = new MailMessage(from, to) ;
mailMessage.Subject="主题";
mailMessage.Body="这是一封来自远方的邮件.";
Attachment attachment01 = new Attachment("E:\\01.jpg"); //附件
Attachment attachment02 = new Attachment("E:\\02.mp3");
mailMessage.Attachments.Add(attachment01);
mailMessage.Attachments.Add(attachment02);
//创建SmtpClient对象 邮箱服务器smtp.163.com
SmtpClient smtpClient = new SmtpClient("smtp.163.com");
smtpClient.UseDefaultCredentials = true;
smtpClient.Credentials =
new NetworkCredential("邮箱账号", "登录密码"); //邮箱认证登录
//smtpClient.Timeout = 5000;
try
{
//使用异步发送,不会阻塞该线程
smtpClient.SendCompleted += new //完成发送调用回调函数
SendCompletedEventHandler(SendCompletedCallback);
smtpClient.SendAsync(mailMessage, mailMessage);
}
catch(Exception ex)
{
mailMessage.Dispose(); //主动释放资源
smtpClient.Dispose();
MessageBox.Show("发送失败! "+System.Environment.NewLine+
"错误信息:"+ex.Message);
}
return;
}
//异步发送完成的回调函数:
//异步发送邮件完成的回调函数
public static voidSendCompletedCallback(object sender, AsyncCompletedEventArgs e)
{
SmtpClientsmtpClient = (SmtpClient)sender;
//MailMessage mailMessage = (MailMessage)e.UserState;
if (e.Cancelled)
{
MessageBox.Show("Send canceled.");
}
if (e.Error !=null)
{
MessageBox.Show("错误信息: "+e.Error.ToString() );
}
else
{
MessageBox.Show("Message Sent.");
smtpClient.Dispose();
//mailMessage.Dispose();
}
}
总结:通过两种方式实现了简单的邮件发送功能,从中可以比较这两种语言在实现上的差异性,
C语言的实现更加讲究流程和细节,你需要比较深的懂得网络的相关知识和SMTP的相关协议,
优点是可以更加直接的操作邮件的发送过程,缺点就是实现起来比较繁琐,容易异常.
C#的实现就更加简洁明了了,它封装了邮件发送过程中的很多细节,这些细节对用户来说并不是
必要的,使用者只需要知道几个重要的类(MailMessage,SmtpClient类)的使用,而且程序一般会比
C程序要来的稳定,不容易发生异常错误.