过平台的.NET邮件协议MailKit组件解析

   发起的.NET
Core开源组织号召,进展的速是自己要好吧从没想到的,很多园友都积极参与(虽然小人率真砸场子,要是因为自己先的宝脾气,这会应让自己于住院了吧,不过幸而是少数,做同项事究竟有人说好,也有人说是用武汉话说“闹眼子”),.NET社区不是绝非愿意共享知识的人,只是没有一个整体和可以的生态环境,总之要国内的.NET发展更为强大。我以此间想到一句话“我们盼望自己得做巨浪,但我们为心甘情愿做巨浪来袭前的小浪”。

golang 很好用,不过要拿工具链弄了整.
要无你见面发现怎么不克编译跨平台的呀? 怎么形容代码没提醒啊? …

 
 上面拉了(我当时口关系正事前,都如以有拉扯的言语,这个习惯变更不丢了…)

当时身折腾下来并无容易. 所以精心准备了同样拟工具方便大家以.
软件列表如图. 安装顺序比较主要,依次为:
wxdevcpp_7.4.2_full_setup.exe
go1.7.3.windows-386.msi
liteidex30.3.windows-qt5.zip

 
 项目蒙为了这的通信,有直接发多少及页面,也发下短信通知,也时有发生我门今天牵线的邮件组件。我们今天的重要性任务就是是教一下发出一个.NET底免费开源之邮件组件MailKit。本文将仍的组合实例和零部件底层代码讲解一下系组件的学识。(项目招人的当儿,我都见面咨询一样下.NET的脚原理,有一个大神问我这么发生什么含义吗?我们也写不出.NET底层那样的优良处理方式,为何取了解这些,其实自己个人认为,问底的法则,只是于为跟好之处理局部序出现的题目,以及针对性先后编码的上,选择最合适的主意提升性,任何一样栽方法还生优势与劣势,.NET的类库代码也是这般,如果我们知道.NET的底层实现,我们在项目之需求实现时,可以根据.NET底层实现,选择适用的不二法门,以要性能最优异)。

故是 golang 跨平台编译需要 gcc,而 liteide 又欲它两者.

一.Mailkit组件概述

 
 项目中使Email的操作时比多,一般小好一些底档次,都见面采用到邮件操作就一个操作。对于.NET邮件操作的机件和方式比多,今天咱们就算介绍一舒缓邮件操作的零部件MailKit,这个邮件组件是一个开源免费之,我们本尽管来询问一下当下一个零件的特性。MimeKit旨在通过尽可能接近地本MIME规范来解决这个题材,同时还也程序员提供了一个非常容易使用的高级API。

 
 组件的支持的客户端类型比较多,例如SMTP客户端、POP3客户端、IMAP客户端。该器件是一个跨平台的Email组件,该器件支持.NET
4.0,.NET 4.5,Xamarin.Android,Xamarin.iOS,Windows Phone
8.1之类平台。该器件提供了一个MIME解析器,组件有的剖析特性灵活、性能大、很好之拍卖千头万绪的烂的MIME格式化。MimeKit的习性实际上和GMime相当。

   该器件在安全性的尚是较高的,处理平安之法于多,SASL认证、支持S /
MIME v3.2、支持OpenPGP、支持DKIM签名等等方式。Mailkit组件可以经过CancellationToken取消相应之操作,CancellationToken传播应取消操作的打招呼,一个底CancellationToken使线程,线程池工作类里面,或取消合作任务的靶子。过实例化CancellationTokenSource对象来创造取消令牌,该对象管理起那个CancellationTokenSource.Token属性检索的撤令牌。然后,将注销令牌传递至该接收取消通知的任性数量之线程,任务或操作。令牌不可知用来启动取消。

  MailKit组件支持异步操作,在里边编写的关于I/O异步操作的类似。


二.MailKit实例:

   
上面介绍了MailKit组件的背景和特征,这里就是介绍一下Email组件之简约用。

(地址是 golang 大集合,请进入其
“go1.7.3合集”子目录):
https://pan.baidu.com/s/1c3MLKo4

  1.开立邮件方式:

 public void SentEmail(string path)
        {
            var message = new MimeMessage();
            //获取From标头中的地址列表,添加指定的地址
            message.From.Add(new MailboxAddress("Joey", "joey@friends.com"));
            //获取To头中的地址列表,添加指定的地址
            message.To.Add(new MailboxAddress("Alice", "alice@wonderland.com"));
            //获取或设置消息的主题
            message.Subject = "How you doin?";
            // 创建我们的消息文本,就像以前一样(除了不设置为message.Body)
            var body = new TextPart("plain")
            {
                Text = @"Hey Alice-- Joey"
            };
            // 为位于路径的文件创建图像附件
            var attachment = new MimePart("image", "gif")
            {
                ContentObject = new ContentObject(File.OpenRead(path), ContentEncoding.Default),
                ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
                ContentTransferEncoding = ContentEncoding.Base64,
                FileName = Path.GetFileName(path)
            };
            // 现在创建multipart / mixed容器来保存消息文本和图像附件
            var multipart = new Multipart("mixed")
            {
                body, attachment
            };
            // 现在将multipart / mixed设置为消息正文 
            message.Body = multipart;
        }

 
 调用该器件发送邮件与也邮件上加附件是比较简单的,第一步是实例化MimeMessage对象,对于该对象的辨析将于脚进行,得到MimeMessage对象后,指定邮件的地址及主题等等相关消息。第二步实例化TextPart对象,为对象设定文本信息。若需咨询邮件创建文件的附件,可以应用MimePart对象,包含内容(如信息正文文本或)的叶节点MIME部分一个附件。第四步为创造的邮件主体与文件和附件信息后,可以创造Multipart对象,创建邮件容器,用来装文本信息与附件。最后调用MimeMessage.body属性获取或设置信息之正文。

[图片]

    2.邮件信息之辨析:

var message = MimeMessage.Load(stream);

 
 邮件的音我们用进行对应之解析,这里我们使用MimeMessage的Load方法,该方式从指定的流加载MimeKit.MimeMessage。另一个加载数据的法,可以利用MimeParser类,这里就是不再解析了。

    3.邮件的收:

   public static void HandleMimeEntity(MimeEntity entity)
        {
            //MimeEntity转化为Multipart实体
            var multipart = entity as Multipart;
            if (multipart != null)
            {
                for (int i = 0; i < multipart.Count; i++)
                    HandleMimeEntity(multipart[i]);
                return;
            }
            var rfc822 = entity as MessagePart;

            if (rfc822 != null)
            {
                var message = rfc822.Message;
                HandleMimeEntity(message.Body);
                return;
            }
            var part = (MimePart)entity;
        }

 
 以上是针对性收到至之音之一个遍历,采用递归遍历MIME结构。MIME是情之培育结构,很像一个文件系统。MIME确实定义了同一组通用规则,用于邮件客户端如何分解MIME部分的树结构。的 内容处置头是为为接受客户端提供提醒为什么样有凡是为显得作为消息体的相同有的,并且完全在让诠释吗附件。另外两栽办法立即距就无举行牵线了。

 

三.MailKit核心对象解析

 
 上面介绍了Email的基本操作就未举行过多的牵线,在使该器件时,较为的简短。这里就是来探该器件的类别结构与有些中心目标。类库结构来如下图:

 

    1.MimeMessage.Load():

public static MimeMessage Load (ParserOptions options, Stream stream, bool persistent, 
                                CancellationToken cancellationToken = default (CancellationToken))
        {
            if (options == null)
                throw new ArgumentNullException (nameof (options));

            if (stream == null)
                throw new ArgumentNullException (nameof (stream));

            var parser = new MimeParser (options, stream, MimeFormat.Entity, persistent);

            return parser.ParseMessage (cancellationToken);
        }

   
 该措施从指定的流加载MimeMessage,具有6只章程重载。该办法返回一个MimeMessage对象,有源码可以看来,在该措施中创立了一个MimeParser对象,MimeParser包含内容(例如邮件正文文本或附件)的叶节点MIME部分。调用ParseMessage方法,解析来自流的信息。

   2.TextPart.Text:

public string Text {
            get {
                if (ContentObject == null)
                    return string.Empty;
                var charset = ContentType.Parameters["charset"];
                using (var memory = new MemoryStream ()) {
                    ContentObject.DecodeTo (memory);
                    var content = memory.ToArray ();
                    Encoding encoding = null;
                    if (charset != null) {
                        try {
                            encoding = CharsetUtils.GetEncoding (charset);
                        } catch (NotSupportedException) {
                        }
                    }
                    if (encoding == null) {
                        try {
                            return CharsetUtils.UTF8.GetString (content, 0, (int) memory.Length);
                        } catch (DecoderFallbackException) {
                            encoding = CharsetUtils.Latin1;
                        }
                    }
                    return encoding.GetString (content, 0, (int) memory.Length);
                }
            }
            set {
                SetText (Encoding.UTF8, value);
            }
        }

   
该属性获取解码的公文内容。该属性是一个可是读而写的特性。ContentType.Parameters[“charset”]用于获取charset参数的价。该方法用来以参数的值设置也数流并设置相应的编码。看到此的大处理组织,就想大概的语几句子,.NET的怪比较的软弱,很多早晚以写.NET的死时便更是的粗略,以上是针对异常知识捕获,有些地方并没举行拍卖,有些地方是本着那个的地方进行复原。


   3.MimeEntity.WriteTo():

public virtual void WriteTo (FormatOptions options, Stream stream, bool contentOnly, 
                            CancellationToken cancellationToken = default (CancellationToken))
        {
            if (options == null)
                throw new ArgumentNullException (nameof (options));

            if (stream == null)
                throw new ArgumentNullException (nameof (stream));

            if (!contentOnly)
                Headers.WriteTo (options, stream, cancellationToken);
        }

   
该办法将MimeEntity写副到指定的数据流中,该措施接受参数options格式选项。stream输出数据流,contentOnly判断是否可写。该办法定义为虚方法,在延续这办法后,可以在子类种对拖欠方式开展重写。

编译的艺术参考了园网友的章,不过 wxdevcpp
更爱找到,而且是自身一直还用之编译器,所以用了她带的 gcc.

四.总结

 
 本人觉得以档次开支中,如果引入了第三正在组件,我们尽量引入组件的源码,这样咱们针对所有组件的结构发生一个认识,组件的兑现方式我们呢可以展开细心了解,尤其是咱们在开展调试之下愈加有因此,我们可逐一的拓断点调试。以上是针对该器件的一个简约介绍,有趣味的可去深入之垂询以及学。

from
http://softhub.newbt.net/160/%7BBFEF9B7F-9993-9A8D-FFB4-CF6EECA4F767%7D-0.html

Golang于windows下交叉编译linux程序 [转贴加 clq
的修正]
2016-04-19 15:17 by 埋头前进的码农, 3494 阅读, 0 评论, 收藏, 编辑

1、下充斥相关程序。

  Golang下载:http://www.golangtc.com/download

  Git下载:http://git-scm.com/download/

  TDM-GCC下载:http://tdm-gcc.tdragon.net/download

2、Go编译环境布置

  安装
TDM-GCC,程序会自动装PATH环境变量,如果没设置成请手动设置。

  安装Go,安装完后要设置GOROOT,GOPATH,GOBIN,PATH环境变量,

  其中  

  GOROOT为汝的Go安装跟目录

  GOPATH为公go程序开发目录,go get后的担保也会生充斥及该目录。

  GOBIN为卿的go运行目录,运行 go install
命令后,程序会受装及该目录。

  PATH为卿Go程序根目录,用于能够由此控制台调用go命令。

3、配置交叉编译环境

  以Go根目录下之src目录,新建一个build.bat文件,并复制内容如下:
复制代码

set CGO_ENABLED=0
set GOROOT_BOOTSTRAP=C:/Go
::x86块
set GOARCH=386
set GOOS=windows
call make.bat –no-clean
 
set GOOS=linux
call make.bat –no-clean
 
set GOOS=freebsd
call make.bat –no-clean
 
set GOOS=darwin
call make.bat –no-clean
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
::x64块
set GOARCH=amd64
set GOOS=linux
call make.bat –no-clean
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
::arm块
set GOARCH=arm
set GOOS=linux
call make.bat –no-clean
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 
set GOARCH=386
set GOOS=windows
go get github.com/nsf/gocode
pause

复制代码

  我之Go程序版本是1.6,需要装GOROOT_BOOTSTRAP变量为Go的安装目录,否则执行时会报错。

  然后运行build.bat,等待了。

  该次会编译其他平台编译Go需要之仓库以及编译文件。

  完成后,在cmd命令行下依次执行:

  set GOOS=linux

  set GOPACH=amd64

  go build -o -x APPNAME main.go

  编译后底文书会面世在main.go相应的目下。


上述是转贴网友文章,对于自的 go 1.7.3 环境虽然有些不同.
有数沾不同:

  1. 用的 wxdevcpp_7.4.2_full_setup 自带的 gcc.

  2. 末尾一个编译命令没有中标,以下命令成
    D:\gopath>go build  gt21.go