zoukankan      html  css  js  c++  java
  • C和C#两种方式实现邮件的简单发送

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

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

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

    1.创建TCP连接    socket()

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

    3.邮箱用户和密码认证登录   "EHLO smtp.163.com "  →   "AUTH LOGIN "

    4.发送邮件主题内容  

      a.发送 "MAIL FROM:<"邮件的发送方地址"> "  //

        b.发送 "RCPT TO:<"邮件接收方的地址"> "  

         c.发送 "DATA "

         d.发送邮件头(From,To,Subject,Date等),邮件体(邮件体可为空)  

         e.添加附件内容(可以添加多个,附件也可以不添加)

    5.退出登录  发送 "QUIT "

    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      else
    16         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
    ", serverName);                      //"EHLO %s
    "
     7    if (!send_rev(connection, szHello, GENERIC_SUCCESS))
     8       return FALSE;
     9 
    10    //发送AUTH LOGIN
    11    if (!send_rev(connection, "AUTH LOGIN
    ",   AUTHLOGIN_SUCCESS))  // "AUTH LOGIN
    "
    12       return FALSE;
    13 
    14    //发送经过Base64编码的用户账号
    15    char szAccount[100]={0};
    16    base64_encode(userAccount, strlen(userAccount), &szAccount);    //base64编码
    17    strcat(szAccount, "
    ");
    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, "
    ");
    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 From
    21    sprintf(szFrom, "MAIL FROM:<%s>
    ", from);           //  MAIL FROM:<%s>
    
    22    if (!send_rev(connection, szFrom, GENERIC_SUCCESS) )
    23       return FALSE;
    24 
    25    //发送Header中RCPT TO
    26    sprintf(szTo, "RCPT TO:<%s>
    ", to);               //   RCPT TO:<%s>
    
    27    if (!send_rev(connection, szTo, GENERIC_SUCCESS))
    28       return FALSE;
    29 
    30    //发送DATA
    
    31    if (!send_rev(connection, "DATA
    ", DATA_SUCCESS))    //   DATA
    
    32       return FALSE;
    33 
    34    //进行 Body 处理    
    35   sprintf(szFrom, "FROM:%s<%s>
    ", userName, from);     //content
    36    sprintf(szTo, "TO:<%s>
    ", to);
    37    time_t ltime = time(NULL);
    38    _tzset();
    39    sprintf(szDateTime, "Date:%s", ctime(&ltime));
    40    sprintf(szSubject, "Subject:%s
    ", subject);
    41 
    42    sprintf(szBodyHead, "X_Mailer:ntSmtp[ch]
    ", subject);
    43    strcat(szBodyHead, "MIME_Version:1.0
    ");
    44    strcat(szBodyHead, "Content-  type:multipart/mixed;Boundary=ntSmtp
    
    ");
    45    strcat(szBodyHead, "--ntSmtp
    ");
    46    strcat(szBodyHead, "Content-type:text/plain;Charset=gb2312
    ");
    47    strcat(szBodyHead, "Content_Transfer-Encoding:8bit
    
    ");
    48 
    49    sprintf(szBody, "%s
    
    ", 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    {           //将附件内容添加到szContent
    61       AppendAttachment( &szContent, filePath);
    62       //AppendAttachment(&szContent, filePath);
    63    }
    64    //添加结束标记    
    65    strcat(szContent, "
    .
    ");       //  
    .
    
    66 
    67    //发送Content
    68    if ( !send_rev(connection, szContent, GENERIC_SUCCESS) )
    69       return FALSE;
    70 
    71    //发送Quit,退出登录
    72    if( !send_rev(connection, "QUIT
    ", QUIT_SUCCESS) )  //"QUIT
    "
    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("ntsmtp@163.com");
     6     MailAddress to = new MailAddress("miaosha5s@sohu.com");
     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.com
    17     SmtpClient smtpClient = new SmtpClient("smtp.163.com");  
    18     smtpClient.UseDefaultCredentials = true;
    19     smtpClient.Credentials =
    20     new NetworkCredential("邮箱账号", "登录密码");   //邮箱认证登录
    21     //smtpClient.Timeout = 5000;
    22     try
    23     {
    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    else
    16    {
    17      MessageBox.Show("Message Sent.");
    18      smtpClient.Dispose();
    19      //mailMessage.Dispose();
    20    }
    21 }

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

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

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

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

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

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

      附:C语言实现邮件发送的程序代码借鉴自<Windows网络程序设计完全讲义>--作者:高守传

  • 相关阅读:
    SQL Server 2005中NTEXT与NVARCHAR(MAX)
    WiX安装选项开始菜单项
    Linq to SQL 查询Tips
    WCF的Message Logging 和Tracing
    Publish Server Performance Monitors with MsChart
    Pushing Data to a Silverlight Client with a WCF Duplex Service
    IronPython 2.0 发布了
    设置系统环境变量立即生效的VBS脚本
    微软网络数据包分析工具 Microsoft Network Monitor 3.2
    SQL Server 2005最新Service Pack 3
  • 原文地址:https://www.cnblogs.com/miaosha5s/p/4182745.html
Copyright © 2011-2022 走看看