当前位置: 代码迷 >> C# >> C跟C#两种方式实现简单的邮件发送
  详细解决方案

C跟C#两种方式实现简单的邮件发送

热度:337   发布时间:2016-05-05 05:27:47.0
C和C#两种方式实现简单的邮件发送

   内容为通过两种方式发送邮件--1.C语言发送邮件   2.C#发送邮件

一,C语言进行邮件的发送

C语言发送邮件的步骤的简单解析:

1.创建TCP连接    socket()

2.连接到邮箱服务器  SOCKADDR_IN,connect()

3.邮箱用户和密码认证登录   "EHLO smtp.163.com\r\n"  →   "AUTH LOGIN\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连接

1 if ((connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)2 {3     return INVALID_SOCKET;4 }

//连接到邮箱服务器

 1 void ConnectToServer(SOCKET connection,const char *serverName) 2 { 3   //设置SockAddr_In地址结构    4   SOCKADDR_IN serAddr; 5    serAddr.sin_family = AF_INET; 6    serAddr.sin_port = htons(SMTP_PORT); 7    //来自 CAsysSocket::Connect() 8    serAddr.sin_addr.s_addr = inet_addr(serverName); 9    if (serAddr.sin_addr.s_addr == INADDR_NONE)10    {11      LPHOSTENT lphost;12      lphost = gethostbyname(serverName);13      if (lphost != NULL)14         serAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->S_un.S_addr;15      else16         return;17     }18    //连接服务器19    connect(connection, (SOCKADDR *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)20    return;21 }

//认证登录

 1 //认证登录 2 BOOL AuthLogin(SOCKET connection, const char *serverName,const char *userAccount, const char *password) 3 { 4    //发送EHLO%SMTP-Server Name%     说明:HELO 是不带身份验证的,而 EHLO 是带身份验证 5    char szHello[PARA_BUF] = { 0 }; 6    sprintf(szHello, "EHLO %s\r\n", serverName);                      //"EHLO %s\r\n" 7    if (!send_rev(connection, szHello, GENERIC_SUCCESS)) 8       return FALSE; 9 10    //发送AUTH LOGIN11    if (!send_rev(connection, "AUTH LOGIN\r\n",   AUTHLOGIN_SUCCESS))  // "AUTH LOGIN\r\n"12       return FALSE;13 14    //发送经过Base64编码的用户账号15    char szAccount[100]={0};16    base64_encode(userAccount, strlen(userAccount), &szAccount);    //base64编码17    strcat(szAccount, "\r\n");18    if (!send_rev(connection, szAccount, AUTHLOGIN_SUCCESS))        //账号    19       return FALSE;20 21    //发送经过Base64编码的密码22    char szPassword[100]={0};23    base64_encode(password, strlen(password), &szPassword);       24    strcat(szPassword, "\r\n");25    if (!send_rev(connection, szPassword, AUTH_SUCCESS))            //密码26      return FALSE;27    return TRUE;28 }

//发送邮件(包含了用户的退出操作QUIT)

 1 //发送邮件 2 BOOL SendMail(SOCKET connection,const char *from,  const char *to, 3                         const char *subject, const char *body, 4                         const char *userName,const char *filePath) 5 { 6    char szFrom[PARA_BUF] = { 0 }; 7    char szTo[PARA_BUF] = { 0 }; 8    char szSubject[PARA_BUF] = { 0 };  9    char szBodyHead[PARA_BUF * 10] = { 0 };10    char szBody[PARA_BUF * 20] = { 0 };11 12    char szDateTime[PARA_BUF] = { 0 };13    char *szContent=NULL;                14    //邮件的内容,包括正文文本信息,附件内容信息等15   if (!chars_malloc(&szContent, MAX_FILE_SIZE*4/3 + M ) )16    {17       return FALSE;18    }19 20    //发送Header中的Mail From21    sprintf(szFrom, "MAIL FROM:<%s>\r\n", from);           //  MAIL FROM:<%s>\r\n22    if (!send_rev(connection, szFrom, GENERIC_SUCCESS) )23       return FALSE;24 25    //发送Header中RCPT TO26    sprintf(szTo, "RCPT TO:<%s>\r\n", to);               //   RCPT TO:<%s>\r\n27    if (!send_rev(connection, szTo, GENERIC_SUCCESS))28       return FALSE;29 30    //发送DATA\r\n31    if (!send_rev(connection, "DATA\r\n", DATA_SUCCESS))    //   DATA\r\n32       return FALSE;33 34    //进行 Body 处理    35   sprintf(szFrom, "FROM:%s<%s>\r\n", userName, from);     //content36    sprintf(szTo, "TO:<%s>\r\n", to);37    time_t ltime = time(NULL);38    _tzset();39    sprintf(szDateTime, "Date:%s", ctime(&ltime));40    sprintf(szSubject, "Subject:%s\r\n", subject);41 42    sprintf(szBodyHead, "X_Mailer:ntSmtp[ch]\r\n", subject);43    strcat(szBodyHead, "MIME_Version:1.0\r\n");44    strcat(szBodyHead, "Content-  type:multipart/mixed;Boundary=ntSmtp\r\n\r\n");45    strcat(szBodyHead, "--ntSmtp\r\n");46    strcat(szBodyHead, "Content-type:text/plain;Charset=gb2312\r\n");47    strcat(szBodyHead, "Content_Transfer-Encoding:8bit\r\n\r\n");48 49    sprintf(szBody, "%s\r\n\r\n", body);50 51    //连接成content的各部分内容52    strcat(szContent, szFrom);53    strcat(szContent, szTo);54    strcat(szContent, szDateTime);55    strcat(szContent, szSubject);56    strcat(szContent, szBodyHead);57    strcat(szContent, szBody);58 59    if (filePath != NULL)60    {           //将附件内容添加到szContent61       AppendAttachment( &szContent, filePath);62       //AppendAttachment(&szContent, filePath);63    }64    //添加结束标记    65    strcat(szContent, "\r\n.\r\n");       //  \r\n.\r\n66 67    //发送Content68    if ( !send_rev(connection, szContent, GENERIC_SUCCESS) )69       return FALSE;70 71    //发送Quit,退出登录72    if( !send_rev(connection, "QUIT\r\n", QUIT_SUCCESS) )  //"QUIT\r\n"73       return FALSE;74 75    free(szContent);76    return TRUE;77 }


 

二,C#进行邮件的发送

  通过C#进行邮件的发送,不需要C语言那样必须把握住连接通信过程中的诸多细节,

如果进行简单的邮件发送,只需要使用到两个类,一个是MailMessage类,该类定义了

一封完整邮件多需要的信息(包括邮件的发送方,接收方,主题,正文内容,附件等信息),

另一个是SmtpClient类,该类是用于服务器端的操作,通过该类的对象,你就可以设置

邮箱服务器的地址(例如:smtp.163.com),邮箱的登录账号与密码等,最终通过该类

的对象便可以将MailMessage的信息发送到指定的邮箱了.

C#发送邮件的步骤的简单解析:

1.创建MailMessage对象,设置MailMessage的相关成员数据;   包括From,To,Subject,Body,Attachments等信息.

2.创建服务器端对象SmtpClient,设置服务器,邮箱账号,密码.

3.通过SmtpClient对象,将MailMessage邮件信息发送出去;   可以进行普通的发送以及异步发送(不阻塞线程).

 

C#关键代码如下:

 //异步发送邮件

 1 //发送按钮 2 private void btn_Send_Click(object sender, EventArgs e) 3 { 4     //创建MailMessage对象 5     MailAddress from = new MailAddress("[email protected]"); 6     MailAddress to = new MailAddress("[email protected]"); 7     MailMessage mailMessage = new MailMessage(from, to) ; 8     mailMessage.Subject="主题"; 9     mailMessage.Body="这是一封来自远方的邮件.";   10 11     Attachment attachment01 = new Attachment("E:\\01.jpg"); //附件12     Attachment attachment02 = new Attachment("E:\\02.mp3");13     mailMessage.Attachments.Add(attachment01);14     mailMessage.Attachments.Add(attachment02);15 16     //创建SmtpClient对象      邮箱服务器smtp.163.com17     SmtpClient smtpClient = new SmtpClient("smtp.163.com");  18     smtpClient.UseDefaultCredentials = true;19     smtpClient.Credentials =20     new NetworkCredential("邮箱账号", "登录密码");   //邮箱认证登录21     //smtpClient.Timeout = 5000;22     try23     {24     //使用异步发送,不会阻塞该线程25     smtpClient.SendCompleted += new //完成发送调用回调函数26     SendCompletedEventHandler(SendCompletedCallback); 27     smtpClient.SendAsync(mailMessage, mailMessage);   28     }29     catch(Exception ex)30     {31       mailMessage.Dispose();    //主动释放资源32       smtpClient.Dispose();33       MessageBox.Show("发送失败!  "+System.Environment.NewLine+34                    "错误信息:"+ ex.Message);35     }36    return;37 }    

//异步发送完成的回调函数:

 1 //异步发送邮件完成的回调函数 2 public static void SendCompletedCallback(object sender,       3                                     AsyncCompletedEventArgs e) 4 { 5    SmtpClient smtpClient = (SmtpClient)sender; 6    //MailMessage mailMessage = (MailMessage)e.UserState; 7    if (e.Cancelled) 8    { 9      MessageBox.Show("Send canceled.");10    }11    if (e.Error != null)      12    {13      MessageBox.Show("错误信息: "+e.Error.ToString() );14    }15    else16    {17      MessageBox.Show("Message Sent.");18      smtpClient.Dispose();19      //mailMessage.Dispose();20    }21 }

 

 

总结:通过两种方式实现了简单的邮件发送功能,从中可以比较这两种语言在实现上的差异性,

       C语言的实现更加讲究流程和细节,你需要比较深的懂得网络的相关知识和SMTP的相关协议,

优点是可以更加直接的操作邮件的发送过程,缺点就是实现起来比较繁琐,容易异常.

     C#的实现就更加简洁明了了,它封装了邮件发送过程中的很多细节,这些细节对用户来说并不是

必要的,使用者只需要知道几个重要的类(MailMessage,SmtpClient类)的使用,而且程序一般会比

C程序要来的稳定,不容易发生异常错误.

  相关解决方案