内容为通过两种方式发送邮件--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连接

 if ((connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
return INVALID_SOCKET;
}

//连接到邮箱服务器

 void ConnectToServer(SOCKET connection,const char *serverName)
{
//设置SockAddr_In地址结构
SOCKADDR_IN serAddr;
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, const char *serverName,const char *userAccount, const char *password)
{
//发送EHLO%SMTP-Server Name% 说明:HELO 是不带身份验证的,而 EHLO 是带身份验证
char szHello[PARA_BUF] = { };
sprintf(szHello, "EHLO %s\r\n", serverName); //"EHLO %s\r\n"
if (!send_rev(connection, szHello, GENERIC_SUCCESS))
return FALSE; //发送AUTH LOGIN
if (!send_rev(connection, "AUTH LOGIN\r\n", AUTHLOGIN_SUCCESS)) // "AUTH LOGIN\r\n"
return FALSE; //发送经过Base64编码的用户账号
char szAccount[]={};
base64_encode(userAccount, strlen(userAccount), &szAccount); //base64编码
strcat(szAccount, "\r\n");
if (!send_rev(connection, szAccount, AUTHLOGIN_SUCCESS)) //账号
return FALSE; //发送经过Base64编码的密码
char szPassword[]={};
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)
{
char szFrom[PARA_BUF] = { };
char szTo[PARA_BUF] = { };
char szSubject[PARA_BUF] = { };
char szBodyHead[PARA_BUF * ] = { };
char szBody[PARA_BUF * ] = { }; char szDateTime[PARA_BUF] = { };
char *szContent=NULL;
//邮件的内容,包括正文文本信息,附件内容信息等
if (!chars_malloc(&szContent, MAX_FILE_SIZE*/ + M ) )
{
return FALSE;
} //发送Header中的Mail From
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(&ltime));
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 void SendCompletedCallback(object sender,
AsyncCompletedEventArgs e)
{
SmtpClient smtpClient = (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程序要来的稳定,不容易发生异常错误.

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

C和C#两种方式实现邮件的简单发送的更多相关文章

  1. C和C#两种方式实现邮件的简单接收

    本文的主要内容是通过两种方式实现简单邮件的接收,一种方式是通过C语言实现,另一种是通过C#实现的, 两种方式在实现上有许多的不同之处,但是本质上都是一样的. 一,C语言实现方式 C语言接收邮件的步骤: ...

  2. 基于Maven的SpringBoot项目实现热部署的两种方式

    转载:http://blog.csdn.net/tengxing007/article/details/72675168 前言 JRebel是JavaEE中比较流行的热部署插件,可快速实现热部署,节省 ...

  3. Python 实现接口类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现接口类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

  4. Python 实现抽象类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现抽象类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

  5. Android Studio签名打包的两种方式

    签名打包的两种方式: 注:给我们自己开发的app签名,就代表着我自己的版权,以后要进行升级,也必须要使用相同的签名才行.签名就代表着自己的身份(即keystore),多个app可以使用同一个签名. 如 ...

  6. Log4Net日志记录两种方式

     简介 log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具.     log4net是Ap ...

  7. C# 如何通过mailto标签和SMTP协议两种方式发送邮件

    本文主要讲解如何通过如现mailto标签和SMTP协议两种方式发送邮件,下面就直入主题 方法一.通过mailto标签发送邮件 通过mailto不是正真意义上的发送邮件,它只是会自动调用我们本地默认的邮 ...

  8. 分布式理论基础(一)一致性及解决一致性的两种方式:2PC和3PC (转载 不错)

    分布式理论基础(一)一致性及解决一致性的两种方式:2PC和3PC 1 一致性 1.1 简述 一致性,是指对每个节点一个数据的更新,整个集群都知道更新,并且是一致的 假设一个具有N个节点的分布式系统,当 ...

  9. Python 发送 email 的两种方式

    Python发送email的两种方式,分别为使用登录邮件服务器.调用sendmail命令来发送三种方法 Python发送email比较简单,可以通过登录邮件服务来发送,linux下也可以使用调用sen ...

随机推荐

  1. Python下的正则表达式原理和优化笔记

    摘要: 本文旨在总结一些编写表达式的技巧和原理.鉴于介绍python中re模块的使用方法的文章太多.所以本文在基础方面都是略过,而在回溯原理和一些技巧方面记录一点点学习总结. 目录:[ - ] 基础规 ...

  2. abap 开发之创建表维护生成器

    在sap开发中有时需要对一些自建表维护数据,但又不想写程序,怎么办呢??这个时候我们可以直接生成个表维护生成器,为其定义一个事物码就ok了.以下是表格维护生成器的生成步骤. 首先我们需要先定义表.输入 ...

  3. Linux-vim与ssh客户端

    一.vim使用 Linux系统下标准的编辑器,他就相当于windows系统中的记事本一样,它的强大不逊色于任何最新的文本编辑器. (1)vim安装 (2)vim使用:操作模式  一般模式(默认模式,不 ...

  4. 11g ASM新特性

    Oracle 11g的ASM有两个有意思的特性,我们看看他们能带给我们什么? 1.Fast mirror resync 原来当diskgroup中的盘发生故障时,Oracle会将这个盘标记为offli ...

  5. Font: a C++ class

    Font: a C++ class        This class is used in Fractal Generator.    Avi Examples The header fileFon ...

  6. 长网址 短网址(http://www.zhihu.com/question/19852154?rf=21975802)

    短网址(Short URL),顾名思义就是在形式上比较短的网址.通常用的是asp或者php转向,在Web 2.0的今天,不得不说,这是一个潮流.目前已经有许多类似服务,借助短网址您可以用简短的网址替代 ...

  7. [笔记] Ubuntu 18.04源码安装caffe流程

    虽然Ubuntu 18.04可以通过apt安装caffe,但是为了使用最新的代码,还是值得从源码安装一遍的. 安装环境 OS: Ubuntu 18.04 64 bit 显卡: NVidia GTX 1 ...

  8. Linux centos7安装Mongodb

    Linux centos7安装Mongodb-4.0 1.下载 官方下载地址:https://www.mongodb.com/download-center/community 2.上传解压 1)rz ...

  9. python3_Logging模块详解

    python的logging模块提供了通用的日志系统,可以方便第三方模块或应用使用. 简单使用 import logging # logging.config.fileConfig("./l ...

  10. 关于URL和http协议,http消息格式

    转自:http://crystal2012.iteye.com/blog/1447845 在WWW(全球资讯网)中想要连结到某个网页,便需要给浏览器一个位址,而URL在此的功能就是告知浏览器某个资源在 ...