<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_zhuweisky</title><subtitle type="text">君子之行，静以修身，俭以养德。非淡泊无以明志，非宁静无以致远。ESFramework，超强悍的通信框架！ 武汉傲瑞科技有限公司  www.oraycn.com</subtitle><id>http://feed.cnblogs.com/blog/u/12559/rss</id><updated>2012-02-08T03:36:01Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/12559/rss"/><entry><id>http://www.cnblogs.com/zhuweisky/archive/2012/02/08/2342441.html</id><title type="text">ESFramework 安全机制</title><summary type="text">在分布式通信系统中，安全无疑是非常重要的。ESFramework提供了哪些安全保障了？</summary><published>2012-02-08T03:36:00Z</published><updated>2012-02-08T03:36:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2012/02/08/2342441.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2012/02/08/2342441.html"/><content type="html">&lt;p&gt;在分布式通信系统中，安全无疑是非常重要的。ESFramework提供了哪些安全保障了？由于ESFramework是应用层的开发框架，那么本文我们只讨论ESFramework在应用层涉及到的安全问题。如果黑客是在网络层或链路层进行攻击，位于应用层的系统是无能为力的。从应用层来说，安全的重要性主要体现在以下几个方面：&lt;br /&gt;&lt;span style="font-size: 14px;"&gt;（1）&amp;nbsp;防止恶意用户使用格式不正确的消息来试探服务端。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14px;"&gt;（2）&amp;nbsp;防止通信的消息被恶意用户截获，或者，即使被恶意用户截获，也无法破解其内容。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14px;"&gt;（3）&amp;nbsp;防止恶意用户在未成功登录前，就向服务器发送格式正确的伪装消息。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14px;"&gt;（4）&amp;nbsp;防止恶意用户使用巨大数量的空连接来消耗服务器的资源。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ESFramework内置了一些安全机制，以对上述的安全性提供一些保障，下面我们一一说明。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.消息格式验证&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: 14px;"&gt;ESFramework定义了通信消息的总体格式（即消息必须由消息头Header和消息体Body构成），而为了支持快速开发，ESPlus则定义了消息的详细格式（如StreamMessageHeader、TextMessageHeader等）。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="font-size: 14px;"&gt;当网络引擎（无论是服务端的还是客户端的）从网络上接收到一批二进制数据时，会尝试去解析它。如果解析时发现，这批二进制数据的格式不是我们预定义好的消息的格式时，将会认为其是非法消息。此时，网络引擎将会丢弃非法数据，并关闭对应的连接（如果引擎是基于TCP协议的），然后再触发INetEngine接口的InvalidMessageReceived事件。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #808080;"&gt;  ///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 当接收到不完整或无法解析的数据时触发该事件&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;event&lt;/span&gt; &lt;span style="color: #008080;"&gt;CbGeneric&lt;/span&gt;&amp;lt;&lt;span style="color: #008080;"&gt;UserAddress&lt;/span&gt;, &lt;span style="color: #008080;"&gt;MessageInvalidType&lt;/span&gt;&amp;gt; InvalidMessageReceived;&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 事件的参数UserAddress说明了非法消息来源于哪个用户地址；而MessageInvalidType参数则说明了非法消息的类型：&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #808080;"&gt;    ///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 接收到的无效的消息分类。&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;enum&lt;/span&gt; &lt;span style="color: #008080;"&gt;MessageInvalidType&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 正常消息。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        Valid = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 消息尺寸溢出。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        MessageSizeOverflow,&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 无效的消息头&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        InvalidHeader,&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 无效的标识符&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        InvalidToken,&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 数据包长度不够&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        DataLacked,&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 无效的客户端类型&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        InvalidClientType&lt;br /&gt;    }&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp; 从该枚举可以看出，网络引擎收到的数据无法解析的愿意有几种：消息尺寸超过规定的大小，消息头无效、消息的标识符无效等。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.消息加密&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt; 对于一些关键的信息，是绝对不允许以明文的形式在网络上进行传送的。所以，消息在发送之前，必须进行加密。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果直接基于ESFramework开发（不使用ESPlus），那么，熟悉ESFramework骨架流程的朋友都知道IMessageTransformer接口，我们可以将其实现类的实例挂接在骨架流程的对应位置，以对进出的消息进行变形处理。所以，我们可以在IMessageTransformer的实现类中，完成对消息的加密和解密动作，比如，像这样：&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;    public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; &lt;span style="color: #008080;"&gt;MessageEncryptor&lt;/span&gt; : &lt;span style="color: #008080;"&gt;IMessageTransformer&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #008080;"&gt;IMessage&lt;/span&gt; CaptureBeforeSendMessage(&lt;span style="color: #008080;"&gt;IMessage&lt;/span&gt; msg)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;加密消息&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; Encrypt(msg);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #008080;"&gt;IMessage&lt;/span&gt; CaptureReceivedMessage(&lt;span style="color: #008080;"&gt;IMessage&lt;/span&gt; msg)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;解密消息&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;            &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; Decrypt(msg);&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp; 如果使用的是ESPlus提供的Rapid引擎，由于Rapid内部在组装骨架流程时，是没有使用加密组件的，所以不能使用IMessageTransformer接口。但是，我们仍然可以在发送自定义信息时，保证信息的安全。我们是使用ICustomizeOutter发送自定义信息的，以Send方法为例：&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #808080;"&gt;  ///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 向服务器发送信息。&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Send(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;在调用Send方法之前，我们可以先将要发送的内容info进行加密，然后再发送加密后的结果。&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 而在接收方，会调用ICustomizeHandler的HandleInformation方法来处理接收到的信息：&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #808080;"&gt;  ///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 处理来自客户端的自定义信息。&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;param name="sourceUserID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;发送该信息的用户ID&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;  &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;  &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; HandleInformation(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; sourceUserID, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt; 在实现HandleInformation方法时，我们可以先解密info，然后再进行正常的业务处理。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 无论是挂接IMessageTransformer组件，还是在发送或接收自定义信息时，手动加解密信息，都要注意一点，那就是&lt;span style="color: #ff0000;"&gt;加解密都是要消耗CPU和内存资源的，对于那些高频通信的消息来说，这个开销是绝不可忽视的&lt;/span&gt;。所以，我们应该尽可能的只加密那些极其重要的消息/信息（根据MessageType或InfomationType来进行区分），而不是将所有的消息/信息一视同仁。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.验证第一个消息&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt; 有的恶意用户，在破解了消息的格式之后，会尝试在不登录的情况下，向服务器发送其他类型的请求消息。ESFramework支持在服务端对每个连接上收到的第一个消息进行验证，如果验证通不过，则将关闭对应的连接。验证第一个消息的组件的接口是IFirstMessageVerifier：&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;    public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;interface&lt;/span&gt; IFirstMessageVerifier&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; 当每个TCP连接建立成功后，将会验证从该连接上接收到的第一个消息。如果通不过验证，服务端TCP引擎将会关闭对应的连接。&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;param name="firstMessage"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;TCP连接上的第一个消息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;param name="address"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;TCP连接的客户端地址&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt; &lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;验证是否通过&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; VerifyFirstMessage(UserAddress address , IMessage firstMessage);&lt;br /&gt;    }&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;我们可以实现这个接口，并将其注入到ITcpServerEngine对应的属性上。当VerifyFirstMessage方法返回false时，表示验证失败，此时，服务端网络引擎将会关闭对应的TCP连接。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;如果我们使用的是ESPlus提供的Rapid引擎，Rapid引擎内部已经实现了IFirstMessageVerifier接口来为我们验证第一个消息，它主要是保证第一个消息必须是Logon消息，再结合前面介绍的登陆账号密码验证，就可以解决恶意用户在未登录的情况下，就进行其它类型的业务请求的情况出现。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.绑定连接（Session）&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;当Logon消息中的帐号密码通过服务端的验证之后，服务端会将该帐号与对应的TCP连接绑定起来，构成一个完整的Session。如果该连接上接收到的后续消息中，只要发现消息头中的UserID与该TCP连接绑定的帐号不一致，则认为该消息为非法消息，此时，服务端网络引擎将会关闭对应的TCP连接。如此，可以防止用一个帐号登录成功后，再用另一个帐号来请求服务。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.空连接&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt; 到这里，我们已经解决了本文开始提出的前三个问题，这就保证了恶意用户无法向服务器发送恶意的消息了。但是，恶意用户在应用层还可以做一件事情，就是消耗服务端的TCP连接。对于每个已成功建立的TCP连接，服务端都要为其分配一定的资源并对其进行管理。如果恶意的用户和服务器之间建立很多空闲的连接，对服务器资源的消耗也是不可忽视的。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ESFramework提供的服务端引擎ITcpServerEngine支持及时地关闭上述的恶意用户的空闲连接。ITcpServerEngine有一个ExpiredSpanInSecs属性，该属性的含义是：某个TCP连接连上后，如果在ExpiredSpanInSecs时间内服务端网络引擎都接收不到来自该连接的任何数据，则将关闭该连接。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 一般正常的TCP连接建立成功后，客户端会立即向服务器发送Logon消息进行登录。所以，这个机制是可以成立的。我们可以将ExpiredSpanInSecs设为一个有效值（如3s），来减轻空连接的影响。之所以说是&amp;ldquo;减轻&amp;rdquo;，而不是&amp;ldquo;消除&amp;rdquo;，是因为在应用层系统中，无法完全规避这个问题，就按照3秒钟的超时来说，你服务端关闭连接的速度一定赶不上恶意用户建立连接的速度。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 解决这个问题的更好办法，应该是在防火墙上做相关的策略设定，比如屏蔽掉恶意用户的IP地址，过滤由该地址发出TCP握手请求的Syn包，等等。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/2342441.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2012/02/08/2342441.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/zhuweisky/archive/2011/12/19/2293555.html</id><title type="text">ESFramework 使用技巧 －－ 实现监控</title><summary type="text">本文将介绍如何在基于ESFramework/ESPlus开发的系统上增加信息监控的功能。</summary><published>2011-12-19T08:31:00Z</published><updated>2011-12-19T08:31:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2011/12/19/2293555.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2011/12/19/2293555.html"/><content type="html">&lt;p&gt;有些使用ESFramework/ESPlus进行二次开发的朋友，经常来询问要如何做才能在服务端监控客户端发送的所有或部分重要的自定义信息了？鉴于这是一个比较常见的需求，所以，这里我们就简单介绍一下如何在基于ESFramework/ESPlus开发的系统上增加信息监控的功能。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;一.深入ICustomizeInfoOutter接口&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;正如&lt;a id="homepage1_HomePageDays_DaysList_DayItem_7_DayList_7_TitleUrl_2" href="http://www.cnblogs.com/oraycn/archive/2011/10/09/2186241.html"&gt;ESFramework 开发手册（01） －－ 发送和处理信息&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size: 14px;"&gt;一文所介绍的，客户端是使用ESPlus.Application.CustomizeInfo.ICustomizeOutter来发送自定义信息的。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;interface&lt;/span&gt; &lt;span style="color: #008080;"&gt;ICustomizeOutter&lt;/span&gt; :&lt;span style="color: #008080;"&gt;IOutter&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 向服务器发送信息。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Send(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 向在线用户targetUserID发送信息。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="targetUserID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;接收消息的目标用户ID&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Send(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; targetUserID, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 通过P2P通道（不一定可靠）向在线用户targetUserID发送信息。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="targetUserID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;接收消息的目标用户ID&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;  &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="actionType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;当P2P通道不存在时，采取的操作&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; SendByP2PChannel(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; targetUserID, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info ,&lt;span style="color: #008080;"&gt;ActionTypeOnNoP2PChannel&lt;/span&gt; actionType);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 即使与目标用户之间有可靠的P2P通道存在，也要通过服务器转发信息。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="targetUserID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;接收消息的目标用户ID&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; TransferByServer(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; targetUserID, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 向服务器发送信息，并等待服务器的ACK。当前调用线程会一直阻塞，直到收到ACK；如果超时都没有收到ACK，则将抛出Timeout异常。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; SendCertainly(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 向在线用户targetUserID发送信息，并等待其ACK。当前调用线程会一直阻塞，直到收到ACK；如果超时都没有收到ACK，则将抛出Timeout异常。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="targetUserID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;接收消息的目标用户ID&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; SendCertainly(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; targetUserID, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);      &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 向服务器提交请求信息，并返回服务器的应答信息。如果超时没有应答则将抛出Timeout异常。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;      &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义请求信息的类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;请求信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;服务器的应答信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] Query(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 向在线目标用户提交请求信息，并返回应答信息。如果目标用户不在线，或超时没有应答则将抛出Timeout异常。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;      &lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="targetUserID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;接收并处理请求消息的目标用户ID&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义请求信息的类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;请求信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;应答信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] Query(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; targetUserID, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);        &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 向目标组内所有在线用户广播信息。如果groupID传入null，则信息会广播给当前服务器上的所有在线用户。（服务端采用Post）&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="groupID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;接收广播信息的目标组的ID&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; BroadcastInGroup(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; groupID, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);&lt;br /&gt;    }   &lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 该接口的所有方法可以分为两类：一类方法是接收自定义信息的目标用户是服务端；另一类是接收自定义信息的目标用户是其他在线用户。无论是哪种情况，信息都会到达服务端，或由服务端处理、或经服务端转发。（如果客户端之间开启了P2P通道，则稍后再谈。）所以，在服务端是可以监控到客户端通过ICustomizeInfoOutter接口发出的所有自定义信息的。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 另外，关于同步调用服务端或同步调用其它客户端（Query方法）以及组广播信息（BroadcastInGroup）时，所发出的自定义信息也是如此，而且同步调用其它客户端时的返回信息也是经过服务器转发的，所以，也可以被监控到。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 如果客户端之间开启了P2P通道，它们之间的信息将不再经过服务器中转，而是直接经过P2P通道传送，所以这时，服务器就不能监控到这样的信息了。难道就没有办法了吗？不，我们还有一招。对于那些必须要被监控到的信息，客户端可以采用TransferByServer方法进行发送，该方法会强制信息必须通过服务器中转，即使有P2P通道存在也是这样。所以，这里总结的规则是：&lt;span style="color: #ff0000;"&gt;如果在客户端之间传递的某个信息必须要被服务端监控到，那么，客户端就应该调用TransferByServer方法来发送该信息。&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;二.截获自定义信息&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在服务端，我们可以预定ICustomizeController接口的InformationReceived事件，来截获客户端发出的所有自定义信息。&lt;/span&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;  event&lt;/span&gt; &lt;span style="color: #008080;"&gt;CbGeneric&lt;/span&gt;&amp;lt;&lt;span style="color: #008080;"&gt;Information&lt;/span&gt;&amp;gt; InformationReceived; &lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;（1）当收到来自客户端的任何自定义信息时，将触发该事件。要特别注意的是，该事件的处理函数不能抛出异常，否则将导致后续消息处理流程中断。所以，&lt;strong&gt;最好在该事件的处理函数中catch所有的异常&lt;/strong&gt;。&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;（2）该事件处理函数应尽快返回。因为服务端只有在所有的事件函数执行完毕后，才会继续后续的消息处理流程，所以该事件处理函数返回得越快越好。如果有些处理函数的业务逻辑复杂，比较费时，可以考虑使用异步的方式。&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;（3）ICustomizeOutter接口发出的所有自定义信息都包含了相同几个方面的内容：自定义信息的类型、自定义信息的数据、信息的接收者。ESPlus使用Information类来封装这些内容，并且增加了SourceID属性以记录发送者的UserID。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; InformationReceived事件只有一个Information类型参数。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;[&lt;span style="color: #008080;"&gt;Serializable&lt;/span&gt;]&lt;br /&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;class&lt;/span&gt; &lt;span style="color: #008080;"&gt;Information&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; Ctor&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; Information() { }&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; Information(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; _sourceID, &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; _destID, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; _infoType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] _content ,&lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; broadcast)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.sourceID = _sourceID;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.destID = _destID;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.informationType = _infoType;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.content = _content;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;this&lt;/span&gt;.isBroadcast = broadcast;&lt;br /&gt;        } &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; SourceID&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; sourceID = &lt;span style="color: #800000;"&gt;""&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 信息的发送者。可以为UserID或者NetServer.SystemUserID。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; SourceID&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; sourceID; }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt; { sourceID = value; }&lt;br /&gt;        } &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; DestID&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; destID = &lt;span style="color: #800000;"&gt;""&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 信息的接收者。可以为UserID或者NetServer.SystemUserID或GroupID（广播消息）。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; DestID&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; destID; }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt; { destID = value; }&lt;br /&gt;        } &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; InformationType&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 自定义信息类型&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; InformationType&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; informationType; }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt; { informationType = value; }&lt;br /&gt;        } &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; Content&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] content = &lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 信息的内容&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] Content&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; content; }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt; { content = value; }&lt;br /&gt;        } &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#region&lt;/span&gt; IsBroadcast&lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; isBroadcast = &lt;span style="color: #0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 是否为广播消息。如果是，则DestID为groupID。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; IsBroadcast&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; isBroadcast; }&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;set&lt;/span&gt; { isBroadcast = value; }&lt;br /&gt;        } &lt;br /&gt;        &lt;span style="color: #0000ff;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;注意，如果自定义信息的接收者为服务端，则DestID属性的值是NetServer.&lt;span style="color: #008080;"&gt;SystemUserID&lt;/span&gt;（即 "_0"）。&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;（4）当预定了InformationReceived事件后，我们可以根据InformationType来筛选那些我们感兴趣的要监控的自定义信息，并对它们做一些记录或其它业务处理。&lt;/span&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;三.为系统增加监控端&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 有些系统不仅仅需要在服务端监控重要的自定义信息，它还可能有这样的需求：需要一个特殊的客户端，并且只有类似管理员这样的高级用户才能登录这个特殊的客户端，通过该客户端，管理员可以监控到其它普通客户端发送的自定义信息。我们称这个特殊的客户端为监控端。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在有了上面介绍的原理的基础上，实现监控端也相当容易。当服务端在处理ICustomizeController的InformationReceived事件时，将需要被监控的信息转发给在线的监控端就可以了。服务端转发信息给监控端仍然可以使用ICustomizeController的Send方法：&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #808080;"&gt;        ///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 向ID为userID的在线用户发送信息。如果用户不在线，则直接返回。&lt;br /&gt;         &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="userID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;接收消息的用户ID&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;信息&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;void&lt;/span&gt; Send(&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt; userID, &lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType, &lt;span style="color: #0000ff;"&gt;byte&lt;/span&gt;[] info);&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;（1）Send方法的userID参数传入登录监控端的用户的ID。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;（2）将监控到的要转发的信息（InformationReceived事件的参数，即上面提到的被封装成&lt;span style="color: #008080;"&gt;Information&lt;/span&gt;对象）通过序列化后，作为一个新的自定义信息，分别新的将信息类型和序列化结果传入Send方法的第二和第三个参数。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;（3）在监控端处理服务器转发过来的被监控到的信息（可反序列化为&lt;span style="color: #008080;"&gt;Information&lt;/span&gt;对象）以实现监控的业务逻辑即可。&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;四.更多说明&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;请注意，服务端通过预定ICustomizeController接口的InformationReceived事件，只能监控到客户端由ICustomizeOutter接口发出的自定义信息，而不能监控到其它命名空间下的Outter接口发送的消息（注意这里的用词是消息，&amp;ldquo;自定义信息&amp;rdquo;特用于ESPlus.Application.CustomizeInfo空间），比如客户端通过IBasicOutter接口发出的消息，在服务端是不会触发InformationReceived事件的，它们属于不同的命名空间，是相互独立的。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/2293555.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/12/19/2293555.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/zhuweisky/archive/2011/10/29/2228662.html</id><title type="text">ESFramework 使用技巧 －－ 信息处理，分而治之</title><summary type="text">分而治之的所依据的最根本原则是面向对象的基本设计理念 -- 高内聚、低耦合。当CustomizeHandler类变得复杂庞大时，我们就需要将这个CustomizeHandler拆分为多个高内聚低耦合的类，分而治之。</summary><published>2011-10-29T08:38:00Z</published><updated>2011-10-29T08:38:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2011/10/29/2228662.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2011/10/29/2228662.html"/><content type="html">&lt;p&gt;&lt;a href="http://www.cnblogs.com/oraycn/category/323380.html"&gt;ESFramework开发手册&lt;/a&gt;系列文章已经详细介绍了如何使用ESPlus提供的ESPlus.Application.CustomizeInfo空间来发送和处理自定义信息，而且，在我们在前面介绍的&lt;a href="http://www.cnblogs.com/oraycn/archive/2011/10/12/2208237.html"&gt;demo&lt;/a&gt;中，也展示了如何定义信息类型、信息协议，以及如何实现ICustomizeHandler来处理接收到的信息。在一般业务简单的系统中，我们完全可以像demo一样，在一个CustomizeHandler类中处理所有的信息，将所有的业务逻辑集中在这一个地方。但是，当业务逐渐变得复杂时，你会发现，CustomizeHandler类会变得越来越大，而且有很多关联不大的业务逻辑也纠缠在了一起。根据&amp;ldquo;低耦合、高内聚&amp;rdquo;的设计原则，我们需要对这个变得复杂的CustomizeHandler进行拆分，将一个CustomizeHandler拆分为多个高内聚低耦合的类，对收到的信息进行分类，分而治之。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;一.分而治之的设计阶段&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 就像刚才提到的，分而治之的所依据的最根本原则是面向对象的基本设计理念 -- &lt;span style="color: #ff0000;"&gt;高内聚、低耦合&lt;/span&gt;。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在实际的项目中，高内聚、低耦合所针对的分析目标就是我们的业务逻辑， 所以，对CustomizeHandler进行拆分，实际上是对业务逻辑进行拆分。再进一步，那些将被处理的自定义信息，实际上是业务逻辑类型的一个侧面的展示，所以，归根到底，在编码时，最后就是对自定义信息的类型进行拆分。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 假设某个项目的主要业务逻辑可以拆分为A、B、C三类，那么，自定义信息也可以分为A、B、C三类，我们的经验是这样的，将不同类别的信息类型的值（整数）划归到不同的整数段。比如，A类型的自定义信息的类型值为0-100，B类型为101-200，C类型为201-300，当我们要在某类业务逻辑中增加一个信息类型时，就要在对应的数值范围内增加一个数值。这样处理之后，当我们接收到一个自定义信息，根据其类型就可以判断出它是属于哪类业务的了。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在做系统设计时，我们的设计师通常会将所有的信息类型整理成一个&amp;ldquo;协议类型&amp;rdquo;文档并将其定义放到一个dll中，服务端和客户端开发人员都使用这个dll的定义，并遵循文档中的信息类型的规范描述。比如，针对上面的示例可以设计类似如下的&amp;ldquo;协议类型&amp;rdquo;文档：&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/333291/2011112510195285.jpg" alt="" width="441" height="349" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;二.分而治之的实现阶段&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 在将自定义信息分类并完成了信息的格式约定后，就可以实现信息处理器了。针对A、B、C三类业务，理所当然地，我们会实现三个信息处理器分别与之对应，假设命名为ACustomizeHandler、BCustomizeHandler、CCustomizeHandler。现在的问题是，实现了这几个处理器之后，如何将它们挂接到ESFramework/ESPlus框架上了？幸运的是，ESFramework/ESPlus为分而治之这种策略提供了完美的支持，我们不需要再手动去映射信息类型与对应的处理器。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ESPlus.Application.CustomizeInfo命名空间在服务端（Server）和客户端（Passive）都提供了IIntegratedCustomizeHandler接口 -- 可被集成的处理器接口，其定义如下所示：&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #808080;"&gt;    ///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 能够被ComplexCustomizeHandler集成的ICustomizeHandler。&lt;br /&gt;    &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;interface&lt;/span&gt; &lt;span style="color: #008080;"&gt;IIntegratedCustomizeHandler&lt;/span&gt; :&lt;span style="color: #008080;"&gt;ICustomizeHandler&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #008000;"&gt; 当前的处理器能否处理目标类型的自定义信息。&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;param name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;自定义信息的类型&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;        &lt;/span&gt;&lt;span style="color: #808080;"&gt;///&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;能处理？&lt;/span&gt;&lt;span style="color: #808080;"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080;"&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; CanHandle(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType);   &lt;br /&gt;    }&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;IIntegratedCustomizeHandler从ICustomizeHandler继承，说明它可以做与ICustomizeHandler完全一样的事情，只不过，它处理的是整个业务逻辑的一个子集。其增加的CanHandle方法用于说明当前处理器能处理哪些自定义信息。ACustomizeHandler、BCustomizeHandler、CCustomizeHandler 只要实现IIntegratedCustomizeHandler接口就可以了。处理器实现新加的CanHandle方法很简单，比如BCustomizeHandler实现CanHandle的代码如下所示：&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;bool&lt;/span&gt; CanHandle(&lt;span style="color: #0000ff;"&gt;int&lt;/span&gt; informationType)&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;return&lt;/span&gt; informationType &amp;gt;= &lt;span style="color: #800080;"&gt;101&lt;/span&gt; &amp;amp;&amp;amp; informationType &amp;lt;= &lt;span style="color: #800080;"&gt;200&lt;/span&gt;;&lt;br /&gt;  }&lt;/pre&gt;&#xD;
&lt;div &gt;&lt;span &gt;&lt;a onclick="copyCnblogsCode(this)" href="javascript:void(0);"&gt;复制代码&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp; 在实现完了各个业务处理器之后，接下来就需要将它们合成起来，并挂接到ESFramework/ESPlus框架上。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;三.分而治之的合成阶段&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&lt;span style="color: #ff0000;"&gt; 先分后合&lt;/span&gt;，分而治之的最后阶段是&amp;ldquo;合&amp;rdquo;，只有将ACustomizeHandler、BCustomizeHandler、CCustomizeHandler统合起来，才能形成一个完整的业务处理器以处理接收到的所有自定义信息。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ESPlus.Application.CustomizeInfo命名空间在服务端（Server）和客户端（Passive）都提供了ComplexCustomizeHandler类，它是一个综合处理器，相当于一个包装，可以把ACustomizeHandler、BCustomizeHandler、CCustomizeHandler综合在一起，并且ComplexCustomizeHandler又实现了IIntegratedCustomizeHandler接口，这表明了两点：&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&lt;span style="font-size: 14px;"&gt;ComplexCustomizeHandler实现了IIntegratedCustomizeHandler接口，而IIntegratedCustomizeHandler又是继承自ICustomizeHandler接口，所以可以将其直接挂接到ESFramework/ESPlus框架。&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span style="font-size: 14px;"&gt;ComplexCustomizeHandler实现了IIntegratedCustomizeHandler接口，表明其可以再度被其它的ComplexCustomizeHandler集成。就像在一个巨型的系统中，业务逻辑可以被逐级向下拆分，最后可以通过ComplexCustomizeHandler逐级向上合成。&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ComplexCustomizeHandler的实现原理很简单，它只是将接收到的自定义信息分派给正确的处理器去处理，而自己并不参与任何实际的业务过程。其类图如下所示：&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/333291/2011112511153643.jpg" alt="" width="673" height="345" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;针对上面的示例，我们将ACustomizeHandler、BCustomizeHandler、CCustomizeHandler的实例放到ComplexCustomizeHandler的HandlerList中，并且将ComplexCustomizeHandler对象注入到RapidPassiveEngine和RapidServerEngine的Initialize方法中，即可挂接到ESFramework/ESPlus框架。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;四.更多说明&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 14px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 虽然，ESFramework/ESPlus为分而治之这种策略提供了很好的支持，但这并不是实现分而治之策略的唯一的模式。您完全可以抛开IIntegratedCustomizeHandler和ComplexCustomizeHandler，按照自己的习惯和方式，来拆分业务逻辑并进行合成，最后也会殊途同归－－只要我们遵循了&amp;ldquo;低耦合、高内聚&amp;rdquo;这一最根本的设计原则。&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/2228662.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/10/29/2228662.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/zhuweisky/archive/2011/07/07/2099726.html</id><title type="text">奇异的Pinvoke调用</title><summary type="text">我们的一个C#项目需要调用C++的dll，通过Pinvoke进行方法调用。其中的一个方法及其参数的定义是这样的： [StructLayoutAttribute(LayoutKind.Sequential)] publicstructxvid_gbl_info_t{ ///intpublicintversion;///intpublicintactual_version;///char*[MarshalAsAttribute(UnmanagedType.LPStr)]publicstringbuild;///unsignedintpublicuintcpu_flags;///intpublici</summary><published>2011-07-07T01:07:00Z</published><updated>2011-07-07T01:07:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2011/07/07/2099726.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2011/07/07/2099726.html"/><content type="html">&lt;p&gt;我们的一个C#项目需要调用C++的dll，通过Pinvoke进行方法调用。其中的一个方法及其参数的定义是这样的：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;span style="color: #008080"&gt;StructLayoutAttribute&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;(&lt;/span&gt;&lt;span style="color: #008080"&gt;LayoutKind&lt;/span&gt;&lt;span style="color: #000000"&gt;.Sequential)]&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;struct&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;xvid_gbl_info_t&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;int&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;version;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;int&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;actual_version;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;char*&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[&lt;/span&gt;&lt;span style="color: #008080"&gt;MarshalAsAttribute&lt;/span&gt;&lt;span style="color: #000000"&gt;(&lt;/span&gt;&lt;span style="color: #008080"&gt;UnmanagedType&lt;/span&gt;&lt;span style="color: #000000"&gt;.LPStr)]&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;build;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;unsigned&amp;nbsp;int&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;uint&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;cpu_flags;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;int&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;num_threads;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;/span&gt;&lt;span style="color: #008080"&gt;DllImportAttribute(&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;xvidcore&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;EntryPoint&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #800000"&gt;xvid_global&lt;/span&gt;&lt;span style="color: #800000"&gt;"&lt;/span&gt;&lt;span style="color: #000000"&gt;)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;static&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;extern&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;xvid_global(&lt;/span&gt;&lt;span style="color: #008080"&gt;IntPtr&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;handle,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;opt,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;ref&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;xvid_gbl_info_t&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;param1,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IntPtr&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;param2);&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;在做demo时，一切正常，而且在测试的7台电脑上均能正常运行。&lt;/p&gt;&#xD;
&lt;p&gt;但到正式项目中，完全一样的调用模式，却有3台电脑正常运行，4台电脑执行到该方法时就报错：&amp;#8220;有未处理的异常，堆已损坏。&amp;#8221;&lt;/p&gt;&#xD;
&lt;p&gt;昨天晚上搞到半夜，仍然是如此，奇怪！希望有大侠能指教一二，感激不尽。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="color: red"&gt;&amp;nbsp;&amp;nbsp; 注：问题已经解决，原因是不能调用静态方法和成员，如果先调用了静态方法和成员，再调用Pinvoke上面的方法，在某些机器上就会抛出异常。但是为何会这样奇怪了？不得其解。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/2099726.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/07/07/2099726.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/zhuweisky/archive/2011/05/24/2052682.html</id><title type="text">程序员养生 －－ 心态</title><summary type="text">在程序之外，是程序员的生活。 当我们刚刚告别校园成为一个程序员时，大都拥有成功的梦想、万分的激情，那时的我们也拥有精力充沛的健康身体。 随时间流逝，5年过去了、10年过去了，也许，梦想可能渐渐暗淡，激情慢慢消退。但，有一点是肯定的，我们的身体大不如前了，像视力下降、慢性胃炎、颈椎病、失眠、神经衰弱等等接踵而来，这些病症几乎成了我们这个行业的职业病。 从健康的角度来说，程序员这个职业，有几个非常不利...</summary><published>2011-05-24T02:20:00Z</published><updated>2011-05-24T02:20:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2011/05/24/2052682.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2011/05/24/2052682.html"/><content type="html">&lt;p&gt;在程序之外，是程序员的生活。&lt;/p&gt;&#xD;
&lt;p&gt;当我们刚刚告别校园成为一个程序员时，大都拥有成功的梦想、万分的激情，那时的我们也拥有精力充沛的健康身体。 随时间流逝，5年过去了、10年过去了，也许，梦想可能渐渐暗淡，激情慢慢消退。但，有一点是肯定的，我们的身体大不如前了，像视力下降、慢性胃炎、颈椎病、失眠、神经衰弱等等接踵而来，这些病症几乎成了我们这个行业的职业病。&lt;/p&gt;&#xD;
&lt;p&gt;从健康的角度来说，程序员这个职业，有几个非常不利的因素：&lt;/p&gt;&#xD;
&lt;p&gt;第一，程序员需要专注。程序员经常连续长时间地（例如连续8个小时以上，为解决一个bug，饭顾不上吃、睡觉也在想解决方案）专注在一个问题上，这对气血的消耗是非常巨大的。几年前华为一个员工因连续加班而导致过劳死，就是一个典型的例子。&lt;/p&gt;&#xD;
&lt;p&gt;第二，长时间静坐。长时间静坐，导致身体气血循环不畅、经常有某个部分涨痛的情况出现，这就提醒你要多运动运动了。而且，久坐伤胃，过度思虑也伤胃，所以很多程序员都有慢性胃炎这类疾病。&lt;/p&gt;&#xD;
&lt;p&gt;第三，脑力消耗巨大。靠出卖脑力养家活口的程序员，连续的脑力消耗、加上工作方面的精神压力巨大，久而久之，容易患上头痛、偏头痛等毛病。&lt;/p&gt;&#xD;
&lt;p&gt;第四，长时间面对电脑。虽说现在都用LCD显示器，辐射小一些，但是长时间专注地盯着屏幕，对视力的危害是非常大的。而且，久视伤肝，加上经常晚上熬夜加班，程序员就容易肝火旺、眼眶痛（特别是鱼腰穴处）、目赤等。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;身体是自己的，是一辈子的事情。我向来不赞成为了事业，而牺牲健康。（还有，为了利益，而牺牲感情；为了达到目的，而不择手段。）&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&#xD;
&lt;p&gt;想要健康的身体和健康的生活，心态是最重要的。而且，实际上，在诸多的因素中，心态对身体健康的影响是最大的。中医早在几千年前就深刻地认识到了这一点，长期的沉侵在过度的七情（怒喜忧惊悲思恐）之中，对身体的损害相当之大。就正如久郁成疾一样。&lt;/p&gt;&#xD;
&lt;p&gt;随着年纪的增长，心态会慢慢发生变化。以前觉得很重要的，像金钱、名利、地位，慢慢地发现它不是那么重要；以前不以为然的，像亲情、友情，却觉得越来越珍贵。&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&#xD;
&lt;p&gt;今天，已而立之年。就像大多数人一样，不太成功，也不太失败。平淡真实地过着每一天，也许这就是一种幸福的状态的吧。下面就罗列一些我自以为是的观点，仅供大家参考。&lt;/p&gt;&#xD;
&lt;p&gt;（1）不强求、顺其自然。不强求于人，不要让别人难做；也不要强求于事，谋事在人、成事在天。&lt;/p&gt;&#xD;
&lt;p&gt;我们很多痛苦的根源在于，我们太执着了，太强求了。即使有雄心壮志，要做一番大事业，也该是尽人事，听天命。这不是宿命论，而是诸多事情，人算不如天算，塞翁失马焉知非福呢？&lt;/p&gt;&#xD;
&lt;p&gt;（2）掌握事物的规律，抓住关键点，就不用紧张、焦虑，而且往往事半功倍。&lt;/p&gt;&#xD;
&lt;p&gt;比如，我们没有必要不等春天的到来而焦急地在冬天的时候去播种（而现实中，我们为了急于求成，常常在不合时机的时候做不适合的事），因为这违反了自然界的规律，付出一定没有回报。反过来，你也不能因一时懒惰而错过了春天播种、秋天收获的时节，否则，因一时情绪之快，你就要多等一年了。&lt;/p&gt;&#xD;
&lt;p&gt;很多事情，看似无为，实则大为。正像老子说的，无为而无不为。&lt;/p&gt;&#xD;
&lt;p&gt;（3）勤动脑体，不动心。&lt;/p&gt;&#xD;
&lt;p&gt;正常的工作、生活是没问题的（即勤动脑体），但是不要动心。&amp;#8220;动心&amp;#8221;的意思是说，一件事情，你放不下，吃饭的时候也想、睡觉的时候也想，时时刻刻挂在心上，这就是动心了。动心会使气郁，会伤身。&lt;/p&gt;&#xD;
&lt;p&gt;（4）要放得下、要看得开、要放得开。知足常乐。&lt;/p&gt;&#xD;
&lt;p&gt;放得下是魄力、看的开是胸襟、放得开是气度。知足则是最大的精神财富。&lt;/p&gt;&#xD;
&lt;p&gt;（5）失意时要坚韧，得意时要低调。&lt;/p&gt;&#xD;
&lt;p&gt;人生在世，难免有得有失，难免有低潮和春风得意之时。就像，舍得舍得，舍去之后便是得；而得失得失，跟在得后面的就是失。了解这一点，无论是在低潮还是在高潮，我们的情绪都不会太激烈。平淡一点、活得从容。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;路是我们自己选的，拥有一种良好的心态，其实，生活就在我们自己的手中。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt; &lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/2052682.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/05/24/2052682.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/zhuweisky/archive/2011/04/25/2023808.html</id><title type="text">ESFramework 4.0 快速上手（15） －－ 客户端登录验证</title><summary type="text">在之前版本的Rapid引擎中，是没有提供客户端登陆验证的机制的，如果要验证用户的帐号密码信息，我们只有自己手动通过自定义信息来实现。在2011.04.25发布的新版本中，客户端Rapid引擎，则内置了在初始化时验证用户的帐号密码的功能，这使得登录验证变得更加简单。一.ESPlus.Application.Basic 空间的支持 为了实现验证用户账号密码的功能，ESPlus.Application.Basic 命名空间增加了几个基础设施。（1）ESPlus.Application.Basic.Passive.IBasicOutter 增加了Logon方法： ///&amp;lt;summary&amp;gt;/</summary><published>2011-04-25T02:01:00Z</published><updated>2011-04-25T02:01:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/25/2023808.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/25/2023808.html"/><content type="html">&lt;p&gt;在之前版本的Rapid引擎中，是没有提供客户端登陆验证的机制的，如果要验证用户的帐号密码信息，我们只有自己手动通过&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/03/05/1971632.html"&gt;&lt;span style="color: #3366ff"&gt;自定义信息&lt;/span&gt;&lt;/a&gt;来实现。在&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/04/15/2016760.html"&gt;&lt;span style="color: #3366ff"&gt;2011.04.25发布的新版本&lt;/span&gt;&lt;/a&gt;中，客户端Rapid引擎，则内置了在初始化时验证用户的帐号密码的功能，这使得登录验证变得更加简单。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;一.&amp;nbsp;ESPlus.Application.Basic 空间的支持&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;为了实现验证用户账号密码的功能，ESPlus.Application.Basic 命名空间增加了几个基础设施。&lt;/p&gt;&#xD;
&lt;p&gt;（1）ESPlus.Application.Basic.Passive.&lt;span style="color: #008080"&gt;IBasicOutter &lt;/span&gt;增加了Logon方法：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;客户端登陆验证。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="systemToken"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;系统标志。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="password"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;登陆密码&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;LogonResult&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;Logon(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;systemToken,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;password);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;该方法向服务端提交当前登录用户的账号、密码、系统标志等信息，然后返回服务端验证后的登录结果。系统标志systemToken，用于表示当前客户端来自哪个系统，服务端可以验证这个标志是否与服务端匹配，以判断客户端与服务端是否属于同一套系统。在普通的应用中，我们可以忽略它。&lt;/p&gt;&#xD;
&lt;p&gt;登录结果使用&lt;span style="color: #008080"&gt;LogonResult&amp;nbsp;&lt;/span&gt;枚举表示：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;enum&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;LogonResult&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;登陆成功&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Succeed&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;账号或密码错误&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ErrorUserOrPassword,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;已在其它地方登陆&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;HadLoggedOn&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;如果我们的服务端的&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/03/15/1984489.html"&gt;&lt;span style="color: #3366ff"&gt;重登陆模式&lt;/span&gt;&lt;/a&gt;设置为RelogonMode.IgnoreNew，而本次登录所用的UserID已经在线上了，那么Logon方法将返回LogonResult.HadLoggedOn，以表明该用户已在其它地方登录。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;（2）ESPlus.Application.Basic.Server空间增加&lt;span style="color: #008080"&gt;IBasicBusinessHandler&lt;/span&gt;接口&lt;/p&gt;&#xD;
&lt;p&gt;当客户端提交了当前登录用户的账号、密码、系统标志等信息到服务端后，服务端通过调用IBasicBusinessHandler来验证帐户信息。&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IBasicBusinessHandler&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;客户端登陆验证。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="userID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;登陆用户账号&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="systemToken"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;系统标志。用于验证客户端是否与服务端属于同一系统。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="password"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;登陆密码&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;如果密码和系统标志都正确则返回true；否则返回false。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;VerifyUser(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;systemToken,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;password);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;注意，我们在实现IBasicBusinessHandler时，并不需要判断重登陆模式和用户是否已经在线了，这些已经由框架帮我们做好了。所以，VerifyUser方法只是返回一个bool值，来表示帐号密码是否正确。在实现该接口，并将其注入到ESPlus，就可以通过调用IBasicOutter的Logon方法来验证用户了。&lt;/p&gt;&#xD;
&lt;p&gt;框架提供了null object模式的IBasicBusinessHandler实现&lt;span style="color: #008080"&gt;EmptyBasicBusinessHandler&lt;/span&gt;，其在实现VerifyUser方法时，始终返回true。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;二.Rapid引擎内置登录验证&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;本次版本变更中，客户端Rapid引擎和服务端Rapid引擎的Initialize方法都有所变化，以支持用户登录验证的机制。&lt;/p&gt;&#xD;
&lt;p&gt;（1）IRapidPassiveEngine 的Initialize方法：&amp;nbsp;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;LogonResult&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;Initialize(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red"&gt;logonPassword&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;serverIP,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;serverPort,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IBasicBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;basicHandler,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;ICustomizeInfoBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;customizeHandler);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;该方法新增加了登录密码logonPassword参数，并返回登录结果。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #000000"&gt;在内部实现中，&lt;/span&gt;&lt;span style="color: #ff0000"&gt;Initialize方法首先与服务器建立TCP连接，然后通过IBasicOutter的Logon方法发送登录验证请求并获取登录结果&lt;/span&gt;&lt;span style="color: #000000"&gt;，如果登录成功，则直接返回；否则，关闭TCP连接，再返回结果。要注意的是，如果与服务器建立TCP连接失败，Initialize会直接抛出对应的异常，而不是通过返回值来表达。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;IBasicOutter的Logon方法所需的systemToken从哪里来了？IRapidPassiveEngine 新增了一个可读写的属性SystemToken，如果我们设定了它，Logon方法将会将其作为参数值传入。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;在用户登录尝试的过程中，程序可以反复调用Initialize来进行验证，而不需要每次都new一个客户端Rapid引擎实例。只有Initialize方法返回登录成功后，Rapid引擎的相关属性才是可用的。比如，我们可以通过其新增的CurrentUserID属性，来知道当前成功登录的用户的UserID。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;（2）IRapidServerEngine 的Initialize方法：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Initialize(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;port,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;ICustomizeInfoBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;customizeInfoBusinessHandler,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IBasicBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: red"&gt;basicBusinessHandler&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;fileBusinessHandler,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFriendsManager&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;friendsManager,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IGroupManager&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;groupManager);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;服务端Rapid引擎的Initialize方法增加了IBasicBusinessHandler参数，正如前所述，服务端正是通过它来验证客户端提交的帐户信息的。如果我们不关心帐户验证，那么可以传入上面提到的EmptyBasicBusinessHandler实例，或直接传入null -- 此时，引擎内部将默认使用EmptyBasicBusinessHandler来处理用户的登陆验证。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;（3）对于大多数系统，登录时使用账号密码就已经足够。有些特殊的系统，如果在登录时需要验证更多的信息（比如时间戳等），那么大家可以巧用IRapidPassiveEngine的SystemToken属性来传递这些额外的验证信息，因为SystemToken的值也会被提交给服务端的VerifyUser方法进行验证。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;结合本次版本变更，我们已经发布了最新ESFramework、帮助文档、以及更新了所有Demo源码。大家可以从&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 概述&lt;/font&gt;&lt;/a&gt;文末下载。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 概述&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="CategoryEntryList1_EntryStoryList_Entries_TitleUrl_7"  href="http://www.cnblogs.com/zhuweisky/archive/2011/03/24/1993417.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 有哪些优点？&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/04/15/2016760.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 版本升级说明（持续更新）&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292821.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 快速上手》系列所有文章&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292831.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 高级进阶》系列所有文章&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/2023808.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/04/25/2023808.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/zhuweisky/archive/2011/04/21/2018950.html</id><title type="text">ESFramework 4.0 快速上手（14） －－ 聊天系统Demo，增加文件传送功能（附源码）</title><summary type="text">本文我们将介绍在ESFramework 4.0 快速上手（08） －－ 入门Demo，一个简单的IM系统（附源码）的基础上，增加文件传送的功能。如果不了解如何使用ESFramework提供的文件传送功能，可以先看看ESFramework 4.0 快速上手（13） －－ 文件传送，如此简单一文的详细介绍。 本Demo可演示以下与文件传送相关的特性：（1）发送方请求发送文件，接收方可以同意或拒绝接收文件。（2）文件传送的过程中，收发的任何一方都可以通过事件了解文件传送的实时进度。（3）文件传送的过程中，收发的任何一方都可以中断文件的传送。（4）文件传送的过程中，收发的任何一方掉线，都将导致文件传.</summary><published>2011-04-21T01:05:00Z</published><updated>2011-04-21T01:05:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/21/2018950.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/21/2018950.html"/><content type="html">&lt;p&gt;本文我们将介绍在&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/03/25/1994077.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 快速上手（08） －－ 入门Demo，一个简单的IM系统（附源码）&lt;/font&gt;&lt;/a&gt;的基础上，增加文件传送的功能。如果不了解如何使用ESFramework提供的文件传送功能，可以先看看&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/03/29/1998857.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 快速上手（13） －－ 文件传送，如此简单&lt;/font&gt;&lt;/a&gt;一文的详细介绍。&lt;/p&gt;&#xD;
&lt;p&gt;本Demo可演示以下与文件传送相关的特性：&lt;/p&gt;&#xD;
&lt;p&gt;（1）发送方请求发送文件，接收方可以同意或拒绝接收文件。&lt;/p&gt;&#xD;
&lt;p&gt;（2）文件传送的过程中，收发的任何一方都可以通过事件了解文件传送的实时进度。&lt;/p&gt;&#xD;
&lt;p&gt;（3）文件传送的过程中，收发的任何一方都可以中断文件的传送。&lt;/p&gt;&#xD;
&lt;p&gt;（4）文件传送的过程中，收发的任何一方掉线，都将导致文件传送中断。&lt;/p&gt;&#xD;
&lt;p&gt;（5）只要文件传送中断，收发方都会得到相应的事件通知。&lt;/p&gt;&#xD;
&lt;p&gt;（6）自动启用文件断点续传。&lt;/p&gt;&#xD;
&lt;p&gt;（7）文件传送完成，收发方都会得到相应的事件通知。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;一.服务端&lt;/strong&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 服务端只需要用调用引擎RapidServerEngine的初始化方法的另外一个重载就可以启用框架的文件传送功能：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Initialize(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;port,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;ICustomizeInfoBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;customizeInfoBusinessHandler,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;fileBusinessHandler,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFriendsManager&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;friendsManager,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IGroupManager&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;groupManager)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;该重载方法多了一个IFileBusinessHandler（位于ESPlus.Application.FileTransfering.&lt;span style="color: #ff0000"&gt;Server&lt;/span&gt;）参数，我们直接传入框架提供ESPlus.Application.FileTransfering.Server.&lt;span style="color: #008080"&gt;FileBusinessHandler&lt;/span&gt;实例即可。由于在本demo中，服务端即不会是文件发送方、也不会是文件接收方，所以服务端的初始化方法的IFileBusinessHandler参数只要不传入null，就表示服务端会支持客户端之间的文件传送功能。&lt;/p&gt;&#xD;
&lt;p&gt;如果我们要做的是类似FTP的系统，那么这个参数就很重要了，IFileBusinessHandler的实现决定了服务端对客户端上传文件的相关策略。在类似FTP的系统中，我们只要将服务端看做是一个普通的文件收发方，就像一个收发文件的客户端一样，就可以公用同样的文件传送流程了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;二.客户端&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 本Demo演示的主要是客户端之间的文件传送，所以客户端的逻辑稍微复杂一点，我们分解说明如下。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;1.初始化&lt;/strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;客户端引擎RapidPassiveEngine的初始化也需要用另外一个重载方法：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp; void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Initialize(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;serverIP,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;serverPort,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IBasicBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;basicHandler,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;ICustomizeInfoBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;customizeHandler&amp;nbsp;,&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;fileHandler);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;该重载方法也是多了一个IFileBusinessHandler（位于ESPlus.Application.FileTransfering.&lt;span style="color: #ff0000"&gt;Client&lt;/span&gt;）参数，IFileBusinessHandler接口有两个方法：ReadyToAcceptFile方法的实现通常是询问当前用户是否同意接收对方发送的文件；而OnResponseOfReceiver方法的实现通常是告诉发送方对方是否同意了接收文件。Demo中的MainForm类实现了IFileBusinessHandler接口。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.发送文件&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在聊天窗口，当用户点击了左上角的发送文件按钮，并选择了要发送的文件后，程序就会通过&lt;span style="color: #008080"&gt;IFileOutter&lt;/span&gt;接口的BeginSendFile方法来开启文件传送流程。&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;BeginSendFile(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;accepterID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;filePath,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;comment,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;SendingFileParas&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;paras,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;out&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileID);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;我们可以通过SendingFileParas参数来控制文件数据包的发送策略。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BeginSendFile方法调用后，接收方将会通过上述的ReadyToAcceptFile方法得到通知，如果同意接收，则发送方就会通过上述的OnResponseOfReceiver方法得到通知，且框架会自动在后台开启文件传送线程。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.传输文件状态显示&lt;/strong&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 当文件传送正式开始以后，我们就需要了解当前文件传输的状态。本Demo直接使用了ESPlus提供的ESPlus.FileTransceiver.Widgets.FileTransferingViewer控件。我们将这个控件从工具箱拖拽到聊天窗口右边的Panel上，然后将其传入&lt;span style="color: #008080"&gt;IFileOutter&lt;/span&gt;的InitializeFileTransferingViewer方法进行初始化后，它就能正常工作了。本demo中，我们在ChatForm类的构造函数中初始化该控件。&lt;/p&gt;&#xD;
&lt;p&gt;在运行时，我们可以在该控件上显示的正在传送的文件的Item上点击&amp;#8220;取消&amp;#8221;按钮，以中断文件传输 -- 控件会自动将该动作传递给框架以自动取消，我们在代码中不需要再做任何取消传送的处理。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.文件传送事件处理&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们在ChatForm类中预定了FileTransferingViewer的几个事件，来接收文件传送的相关事件通知，以在UI上显示告诉当前用户：文件传送开始、中断、完成、续传等。如果你的项目中不需要用到FileTransferingViewer，那么可以通过预定ESPlus.Application.FileTransfering.&lt;span style="color: #008080"&gt;IFileController&lt;/span&gt;接口暴露的&lt;span style="color: #000000"&gt;FileSendingEvents&lt;/span&gt;和&lt;span style="color: #000000"&gt;FileReceivingEvents来跟踪每个文件传送项目的状态。&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5. 关闭聊天窗口的时候，中断文件传输&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/strong&gt;当与对方有多个文件正在传送中，点击关闭聊天窗口，我们需要调用IFileOutter接口的CancelFileTransferingAbout方法来取消与当前聊天对象正在进行的所有文件传输。&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;CancelFileTransferingAbout(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;destUserID);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;众多其它细节，已经在&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/03/29/1998857.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 快速上手（13） －－ 文件传送，如此简单&lt;/font&gt;&lt;/a&gt;一文中作了详细介绍，这里不再赘述。大家可以参考上文和本文，然后对照源码进行研究，很容易就可以理解内部的运转流程了。&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;三.Demo源码下载&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Demo运行截图如下所示：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/zhuweisky/ESF_FileTransfer2.jpg" width="440" height="185" /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://files.cnblogs.com/zhuweisky/RapidEngineDemoFileTransfer.rar"&gt;&lt;span style="color: #0000ff"&gt;下载本文的Demo源码&lt;/span&gt;&lt;/a&gt;（VS2005）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;本Demo主要演示了客户端与客户端之间的文件传送，后面我们将推出一个新的demo，用于演示客户端与服务端之间的文件传送，以实现最简单的的FTP服务器（文件上传与下载）。敬请关注，谢谢。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 概述&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="CategoryEntryList1_EntryStoryList_Entries_TitleUrl_7"  href="http://www.cnblogs.com/zhuweisky/archive/2011/03/24/1993417.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 有哪些优点？&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/04/15/2016760.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 版本升级说明（持续更新）&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292821.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 快速上手》系列所有文章&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292831.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 高级进阶》系列所有文章&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/2018950.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/04/21/2018950.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/zhuweisky/archive/2011/04/20/1998857.html</id><title type="text">ESFramework 4.0 快速上手（13） －－ 文件传送，如此简单</title><summary type="text">在所有的通信系统中，文件传送是最常见也是最重要的功能之一，ESFramework对文件传送的强大支持也是其亮点之一，使用ESFramework可以非常轻松地实现与文件传送相关的所有需求。ESPlus.Application.FileTransfering命名空间完整地解决了通信中与文件收发相关的问题，可以支持客户端与客户端之间的文件对传、上传文件到服务器以及从服务器下载文件，并且可以监控每个文件传送的实时状态、且内置了文件续传等功能。一.ESPlus的文件传送流程 ESPlus定义了文件传送的标准流程，可以用下图表示： （1）由发送方发起传送文件的请求。（2）接收方回复同意或者拒绝接收文件。.</summary><published>2011-04-20T01:10:00Z</published><updated>2011-04-20T01:10:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/20/1998857.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/20/1998857.html"/><content type="html">&lt;p&gt;在所有的通信系统中，文件传送是最常见也是最重要的功能之一，ESFramework对文件传送的强大支持也是其亮点之一，使用ESFramework可以非常轻松地实现与文件传送相关的所有需求。ESPlus.Application.FileTransfering命名空间完整地解决了通信中与文件收发相关的问题，可以支持客户端与客户端之间的文件对传、上传文件到服务器以及从服务器下载文件，并且可以监控每个文件传送的实时状态、且内置了文件续传等功能。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;一.ESPlus的文件传送流程&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;ESPlus定义了文件传送的标准流程，可以用下图表示：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img style="width: 530px; height: 347px" border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/zhuweisky/ESPlus_FileTrans.jpg" width="530" height="347" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;（1）由发送方发起传送文件的请求。&lt;/p&gt;&#xD;
&lt;p&gt;（2）接收方回复同意或者拒绝接收文件。如果拒收，则流程结束；否则进入下一步。&lt;/p&gt;&#xD;
&lt;p&gt;（3）发送方发送文件数据，接收方接收文件数据。&lt;/p&gt;&#xD;
&lt;p&gt;（4）如果文件传送过程中，接收方或发送方掉线或者取消文件传送，则文件传送被中断，流程结束。如果文件传送过程一直正常，则到最后完成文件的传送。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;有几点需要说明一下：&lt;/p&gt;&#xD;
&lt;p&gt;（1）发送方可以是客户端，也可以是服务器；接收方也是如此。但无论发送方和接收方的类别如何，它们都遵守这一文件传送流程；就像ESFramework所有的&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/03/18/1987850.html"&gt;&lt;span style="color: #3366ff"&gt;通信引擎&lt;/span&gt;&lt;/a&gt;都公用同一套消息处理&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/03/17/1986727.html"&gt;&lt;span style="color: #3366ff"&gt;骨架流程&lt;/span&gt;&lt;/a&gt;一样。&lt;/p&gt;&#xD;
&lt;p&gt;（2）当接收方同意接收后，框架会自动搜索是否存在匹配的续传项目，若存在，则会启动断点续传。当然，我们可以通过文件接收管理器的属性来控制断点续传功能是否开启。关于断点续传的更多内容，可以参考&lt;a id="homepage1_HomePageDays_DaysList_DayItem_16_DayList_16_TitleUrl_0"  href="http://www.cnblogs.com/zhuweisky/archive/2011/01/25/1944436.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 文件断点续传原理与实现&lt;/font&gt;&lt;/a&gt;。&lt;/p&gt;&#xD;
&lt;p&gt;（3）进行文件传送的线程是由框架自动控制的，只要发送方收到了接收方同意接收的回复，框架就会自动在后台线程中发送文件数据包；同样，此时接收方也会自动处理接收到的文件数据包。&lt;/p&gt;&#xD;
&lt;p&gt;（4）发送方或接收方都可随时取消正在传送的文件。&lt;/p&gt;&#xD;
&lt;p&gt;（5）当文件传送被中断或完成时，发送方和接收方都会有相应的事件通知。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;二.ESPlus用于支持文件传送的基础设施&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.TransmittingFileInfo&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;无论是发送方还是接收方，针对每个文件传送任务，都需要有个对象来表示它，TransmittingFileInfo便是一个文件传送项目的封装，里面包含了类似发送者ID、接收者ID、文件名称等相关信息。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/zhuweisky/ESPlus_TransInfo.jpg" width="232" height="394" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;TransmittingFileInfo的大部分属性对于发送方和接收方都是有效的，而有几个属性只对发送方有效（比如SendingFileParas），有几个属性只对接收方有效（如LocalSaveFilePath），这些在帮助文档中都有详细的说明。而且，有些属性（如OriginFileLastUpdateTime）的存在是用于支持断点续传功能的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.FileTransDisrupttedType&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;ESPlus使用FileTransDisrupttedType枚举定义了所有可能导致文件传送中断的原因：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;enum&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;FileTransDisrupttedType&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;自己主动取消&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ActiveCancel,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;对方取消&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DestCancel,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;对方掉线&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DestOffline,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;网络中断、自己掉线&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SelfOffline,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;对方拒绝接收文件&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;DestReject,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;其它原因，如文件读取失败等&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OtherCause&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;3.IFileTransferingEvents 接口&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;ESPlus定义了IFileTransferingEvents接口，用于暴露所有与文件传送相关的状态和事件：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileTransferingEvents&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;当某个文件开始传送时，触发该事件。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbGeneric&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #008080"&gt;TransmittingFileInfo&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileTransStarted;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;当某个文件续传开始时，触发该事件。（将不再触发FileTransStarted事件）&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbGeneric&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #008080"&gt;TransmittingFileInfo&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileResumedTransStarted;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;文件传送的进度。参数为fileID（文件编号）&amp;nbsp;,total（文件大小）&amp;nbsp;,transfered（已传送字节数）&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbFileSendedProgress&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;FileTransProgress;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;文件传送中断时，触发该事件。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbGeneric&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #008080"&gt;TransmittingFileInfo&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;FileTransDisrupttedType&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileTransDisruptted;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;文件传送完成时，触发该事件。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbGeneric&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #008080"&gt;TransmittingFileInfo&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileTransCompleted;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;通过预定这些事件，我们可以知道每个传送的文件什么时候开始（或断点续传）、什么时候完成、传递的实时进度、传送中断的原因等等。要注意的是，这些事件都是在后台线程中触发的，如果在事件处理函数中需要更新UI，则需要将调用转发到UI线程。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;4.SendingFileParas&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;该对象仅仅包含两个属性：SendingSpanInMSecs和FilePackageSize。发送方可以通过SendingFileParas对象来指定发送文件数据包时的频率与每个数据包的大小。一般来说，为了达到最快的传送速度，SendingSpanInMSecs可以设为0。而FilePackageSize的大小则要根据发送方与接收方的网络环境的好坏进行决定，在Internet上，一般可以设为2048或4096左右；而在局网内，可以设为204800甚至更大（在局网的传送速度可以达到30M/s以上）。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;5.IFileController&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;通过ESPlus.Application.FileTransfering.&lt;span style="color: #008080"&gt;IFileController&lt;/span&gt;接口，我们可以提交发送文件的请求，并且可以主动取消正在接收或发送的文件。IFileController即可用于客户端也可用户服务端。&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;&lt;span style="color: #008080"&gt;IFileController&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;该事件接口暴露了所有正在发送文件的实时状态。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileTransferingEvents&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;FileSendingEvents&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;get&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;该事件接口暴露了所有正在接收的文件的实时状态。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileTransferingEvents&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;FileReceivingEvents&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;get&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;准备发送文件。如果对方同意接收，则后台会自动发送文件；如果对方拒绝接收，则会取消发送。&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;如果要发送的文件不存在或被占用，则将抛出对应的异常。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="accepterID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;接收文件的用户ID&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="filePath"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;被发送文件的路径&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/&lt;/span&gt;&lt;span style="color: #808080"&gt;//&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="comment"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;其它附加备注。如果是在类似FTP的服务中，该参数可以是保存文件的路径&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="fileID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;返回即将发送文件的唯一编号&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;BeginSendFile(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;accepterID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;filePath,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;comment,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;out&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileID);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;准备发送文件。如果对方同意接收，则后台会自动发送文件；如果对方拒绝接收，则会取消发送。&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;如果要发送的文件不存在或被占用，则将抛出对应的异常。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="accepterID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;接收文件的用户ID&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="filePath"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;被发送文件的路径&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="comment"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;其它附加备注。如果是在类似FTP的服务中，该参数可以是保存文件的路径&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="paras"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;发送参数设定。传入null，表示采用IFileSenderManager的默认设置。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="fileID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;返回即将发送文件的唯一编号&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;BeginSendFile(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;accepterID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;filePath,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;comment,&lt;/span&gt;&lt;span style="color: #008080"&gt;SendingFileParas&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;paras,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;out&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileID);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;主动取消正在发送或接收的文件，并通知对方。&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;CancelFileTransfering(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileID);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;取消与某个用户相关的正在传送项目。&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #008000"&gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;span style="color: #808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="destUserID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;目标用户ID。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #808080"&gt;&lt;span style="color: #808080"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;CancelFileTransferingAbout(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;destUserID);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;获取正在发送或接收中的文件的相关信息。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;TransmittingFileInfo&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;GetFileInfo(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileID);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;（1）BeginSendFile用于向接收方提交发送文件的请求，如果对方同意，则后台会自动开始传递文件。该方法有个out参数fileID，用于传出标记该文件传送项目的唯一编号，比如，你打算将同一个文件发送给两个好友，将会调用两次BeginSendFile方法，而两次得到的fileID是不一样的。也就是说，fileID是用于标记文件传送&lt;span style="color: #ff0000"&gt;项目&lt;/span&gt;的，而不是标记文件的。&lt;/p&gt;&#xD;
&lt;p&gt;该方法有两个重载，区别在于第二个BeginSendFile方法多了一个SendingFileParas参数，用于主动控制文件数据包的大小和发送频率。&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&#xD;
&lt;p&gt;在客户端使用时，BeginSendFile方法不仅可以向其他在线用户提交发送文件的请求，也可以直接向服务器提交发送文件的请求 -- 即此时文件的接收者为服务端。我们只需要将accepterID参数传入&lt;span style="color: #008080"&gt;NetServer&lt;/span&gt;.SystemUserID，以指明由服务端而不是其他用户来接收即将发送的文件。&lt;/p&gt;&#xD;
&lt;p&gt;（2）GetFileInfo方法可以获取任何一个正在发送或正在接收的项目信息。&lt;/p&gt;&#xD;
&lt;p&gt;（3）CancelFileTransfering方法用于取消正在发送或接收的某个文件传送项目，调用该方法时，框架会自动通知文件传送的另一端用户，并触发&lt;span style="color: #000000"&gt;FileReceivingEvents或FileSendingEvents中的FileTransDisruptted事件，&lt;/span&gt;而另一端也会自动触发FileTransDisruptted事件。&lt;/p&gt;&#xD;
&lt;p&gt;（4）CancelFileTransferingAbout方法用于取消与某个指定用户相关的正在传送项目。比如，我们正在与aa01用户聊天，并且与aa01有多个文件正在传送，此时，如果要关闭与aa01的聊天窗口，那么关闭之前，通常会先调用CancelFileTransferingAbout方法来取消与aa01相关的所有文件传送。所以你经常会看到类似的提示：&amp;#8220;您与aa01有文件正在传送中，关闭当前窗口将导致正在传送的文件中断，您确定要关闭吗？&amp;#8221;。如果用户确认关闭，此时就正是我们要调用CancelFileTransferingAbout方法的时候了。&lt;/p&gt;&#xD;
&lt;p&gt;（5）FileSendingEvents属性用于暴露自己作为发送者的所有正在进行的文件传送项目的实时状态；FileReceivingEvents属性用于暴露自己作为接收者的所有正在进行的文件传送项目的实时状态。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;6.IFileHandler&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;IFileHandler接口将被框架回调以实现文件传送机制。同IFileController一样，其既可用于客户端也可用户服务端。&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;我们需要实现ESPlus.Application.FileTransfering.&lt;span style="color: #008080"&gt;IFileHandler&lt;/span&gt;接口来获取与文件传送请求相关通知：&amp;nbsp; &lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IBusinessHandler&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;是否同意接收文件？&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="senderID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;发送者的ID。如果为NetServer.SystemUserID，则表示是服务端发送的。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="fileName"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;文件名称。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="fileLength"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;文件大小。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="comment"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;其它附加备注。如果是在类似FTP的服务中，该参数可以是保存文件的路径&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="fileID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;文件ID。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="resumedFileItem"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;如果能续传，则不为null。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;返回值为保存文件的路径，如果为null，表示拒绝接收/拒绝续传文件。如果参数resumedFileItem不为null，而且返回路径等于resumedFileItem.LocalFileSavePath，则表示续传；否则表示另存。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;ReadyToAcceptFile(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;senderID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileName,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;long&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileLength,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;comment,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;ResumedFileItem&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;resumedFileItem);&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;接收者对自己发送文件请求的回复&amp;nbsp;--&amp;nbsp;同意/拒绝接收。&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;文件传送项目的相关信息&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="agreed"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;对方是否同意&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;OnResponseOfReceiver(&lt;/span&gt;&lt;span style="color: #008080"&gt;TransmittingFileInfo&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;info&amp;nbsp;,&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;agreed);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;（1）ReadyToAcceptFile方法是当前用户作为&lt;span style="color: red"&gt;接收方&lt;/span&gt;时被框架回调的；而OnResponseOfReceiver方法是当前用户作为&lt;span style="color: red"&gt;发送方&lt;/span&gt;时，被框架回调的。&lt;/p&gt;&#xD;
&lt;p&gt;（2）IFileHandler接口的两个方法都将在后台线程中被框架调用，如果实现该方法时需要刷新应用程序的UI，则注意一定要转发到UI线程。&lt;/p&gt;&#xD;
&lt;p&gt;（3）当发送方提交了发送文件的请求后，框架会在接收方回调ReadyToAcceptFileAsyn方法以询问是否同意接收，如果同意，ReadyToAcceptFileAsyn应返回有效的存储接收文件的路径，否则，返回null。&lt;/p&gt;&#xD;
&lt;p&gt;（4）当接收方同意或拒绝接收文件，框架会在发送方回调OnResponseOfReceiver方法以通知发送者。通常，应用程序在实现OnResponseOfReceiver方法时，最多只需要告知文件发送者，而不需要再做任何其它的额外处理。因为框架已经帮你打理好了一切。&lt;/p&gt;&#xD;
&lt;p&gt;当接收方同意接收文件后，与该文件传送项目相关的事件会通过&lt;span style="color: #008080"&gt;IFileOutter&lt;/span&gt;暴露的IFileTransferingEvents接口相继触发。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;三.客户端&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;同ESPlus的Basic应用或CustomizeInfo应用一样，在客户端支持文件传送功能也需要使用到相应的&amp;#8220;Outter&amp;#8221;组件和实现相应的&amp;#8220;BusinessHandler&amp;#8221;接口。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.IFileOutter&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;ESPlus.Application.FileTransfering.Passive.&lt;span style="color: #008080"&gt;IFileOutter&lt;/span&gt;接口从IFileController继承，并增加了一个属性和一个方法：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileOutter&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IOutter&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;,&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileController&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;发送文件数据包时所采用的消息优先级。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;DataPriority&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;DataPriority4SendingFile&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;get&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;set&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;初始化文件传送查看器控件。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="viewer"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;文件传送查看器控件对象&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="destUserID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;目标用户的ID。返回的查看器将显示与该用户相关的所有文件传送状态。如果传入null，则显示与任何用户的文件传送的实时状态。&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;InitializeFileTransferingViewer(&lt;/span&gt;&lt;span style="color: #008080"&gt;FileTransferingViewer&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;viewer,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;destUserID);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;（1）我们可以通过设置&lt;span style="color: #000000"&gt;DataPriority4SendingFile属性以控制发送文件数据包的优先级，在一般系统中，可以将其设置为Common或Low，但绝不能设置为CanBeDiscarded，否则将可能导致接收方接收到的文件不完整。&amp;nbsp;&lt;/span&gt;&amp;nbsp;&amp;nbsp; &lt;/p&gt;&#xD;
&lt;p&gt;（2）ESPlus提供了默认的传送项目的状态查看器控件&lt;span style="color: #008080"&gt;FileTransferingViewer&lt;/span&gt;，如果没有特殊需求，大家在项目中可以直接使用它来显示文件传送的实时状态，它的界面截图如下所示：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/zhuweisky/ESPlus_TransViewer.jpg" width="186" height="181" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;你只需要把这个控件拖拽到你的UI上，然后将其传入IFileOutter的InitializeFileTransferingViewer方法进行初始化后，它就会正常工作了。&lt;/p&gt;&#xD;
&lt;p&gt;InitializeFileTransferingViewer方法的第二个参数destUserID表示当前的FileTransferingViewer控件要显示与哪个好友相关的所有文件传送项目的状态。以QQ作类比，你同时在与多个好友传送文件，那么就会有多个聊天窗口，每个聊天窗口都会有一个FileTransferingViewer实例，而这个FileTransferingViewer实例仅仅显示与当前聊天窗口对应的好友的传送项目。这样依赖，你与aa01用户传送文件的进度查看器就不会在你与aa02的聊天窗口上显示出来。&lt;/p&gt;&#xD;
&lt;p&gt;如果你的FileTransferingViewer查看器需要捕捉所有正在传送的项目的实时状态，那么，调用InitializeFileTransferingViewer方法时，destUserID参数可以传入null。&lt;/p&gt;&#xD;
&lt;p&gt;另外，FileTransferingViewer实现了&lt;span style="color: #008080"&gt;IFileTransferingViewer&lt;/span&gt;接口：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileTransferingViewer&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;当某个文件开始续传时，触发该事件。参数为FileName&amp;nbsp;-&amp;nbsp;isSend&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbGeneric&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileResumedTransStarted;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;当某个文件传送完毕时，触发该事件。参数为FileName&amp;nbsp;-&amp;nbsp;isSend&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbGeneric&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileTransCompleted;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;当某个文件传送中断时，触发该事件。参数为FileName&amp;nbsp;-&amp;nbsp;isSend&amp;nbsp;-&amp;nbsp;FileTransDisrupttedType&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbGeneric&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;FileTransDisrupttedType&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileTransDisruptted;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;当某个文件传送开始时，触发该事件。参数为FileName&amp;nbsp;-&amp;nbsp;isSend&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbGeneric&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileTransStarted;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;当所有文件都传送完成时，触发该事件。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbSimple&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;AllTaskFinished;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;当点击取消按钮终止某个文件传送时，触发该事件。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CbCancelFile&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;CancelFileButtonClicked;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;当前是否有文件正在传送中。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;IsFileTransfering();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;你也可以通过该接口来关注&lt;span style="color: #008080"&gt;FileTransferingViewer&lt;/span&gt;查看器&lt;span style="color: #ff0000"&gt;捕捉到&lt;/span&gt;&lt;span style="color: #ff0000"&gt;的（正如前所述，不一定是全部）&lt;/span&gt;文件传送项目的状态，而且，该接口的事件都是在UI线程中触发的，你可以直接在其处理函数中操控UI显示。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.IFileBusinessHandler&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;客户端的ESPlus.Application.FileTransfering.Passive.IFileBusinessHandler直接从IFileHandler继承，而且没有增加额外的内容：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IBusinessHandler&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileHandler&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;四.服务端&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;服务端也可以接收客户端发送的文件（即上传），甚至可以发送文件给客户端（即下载），它遵循同样的文件传送流程。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.IFileTransferingController&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如果需要服务端也参与到文件的发送与接收中来，则同客户端一样，服务端的ESPlus.Application.FileTransfering.Server.&lt;span style="color: #008080"&gt;IFileTransferingController&lt;/span&gt;接口也从&lt;span style="color: #008080"&gt;IFileController&lt;/span&gt;继承，以提交文件发送请求、或取消正在发送中的文件等，这里就不重复解释了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.IFileBusinessHandler&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;服务端需要实现ESPlus.Application.FileTransfering.Server.&lt;span style="color: #008080"&gt;IFileBusinessHandler&lt;/span&gt;接口，也是直接从IFileHandler继承，而且没有增加额外的内容。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;五.Rapid引擎对文件传送的支持&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;新版本的&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2010/09/11/1823864.html"&gt;&lt;span style="color: #3366ff"&gt;Rapid引擎&lt;/span&gt;&lt;/a&gt;（可以从&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 概述&lt;/font&gt;&lt;/a&gt;文末下载 ），增加了对文件传送的支持，使用Rapid引擎的朋友可以很方便的利用框架提供的文件传送功能。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1.客户端&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/strong&gt;IRapidPassiveEngine的Initialize方法增加了一个重载：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp; void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Initialize(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;serverIP,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;serverPort,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IBasicBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;basicHandler,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;ICustomizeInfoBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;customizeHandler&amp;nbsp;,&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #ff0000"&gt;fileHandler&lt;/span&gt;&lt;span style="color: #000000"&gt;);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;该重载增加了一个IFileBusinessHandler参数，用于支持文件传送机制。&lt;/p&gt;&#xD;
&lt;p&gt;另外，IRapidPassiveEngine增加了一个IFileOutter只读属性，通过暴露的该属性，我们就可以提交发送文件的请求或监控文件传送的状态了。当然，如果在Initialize方法中没有传入有效的IFileBusinessHandler引用，则FileOutter属性将返回null。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.服务端&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;同客户端一样，服务端IRapidServerEngine的Initialize方法也增加了一个重载：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Initialize(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;port,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;ICustomizeInfoBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;customizeInfoBusinessHandler,&lt;/span&gt;&lt;span style="color: #008080"&gt;IFileBusinessHandler&amp;nbsp;&lt;/span&gt;&lt;span style="color: #ff0000"&gt;fileBusinessHandler&lt;/span&gt;&lt;span style="color: #000000"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IFriendsManager&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;friendsManager,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;IGroupManager&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;groupManager);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;IRapidServerEngine提供了IFileTransferingController只读属性，用于提交发送文件的请求或监控文件传送的状态。同样的，如果在Initialize方法中没有传入有效的IFileBusinessHandler引用，则FileTransferingController属性将返回null。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Rapid引擎已经为我们组装好了与文件传送相关的所有组件，我们直接使用即可。如果后面有时间，我们会更深入地剖析ESPlus的文件传送机制背后的原理，以及如何一步步地搭建起文件传送的功能。&lt;/p&gt;&#xD;
&lt;p&gt;ESPlus使得在基于ESFramework的通信系统中增加文件传送的功能变得如此简单，甚至，基于ESPlus提供的文件传送功能，我们可以很快地实现文件服务器，以支持文件上传和下载。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/04/17/2018950.html"&gt;&lt;span style="color: #3366ff"&gt;接下来的一篇文章&lt;/span&gt;&lt;/a&gt;中，我们将在&lt;a id="homepage1_HomePageDays_DaysList_DayItem_0_DayList_0_TitleUrl_0"  href="http://www.cnblogs.com/zhuweisky/archive/2011/03/25/1994077.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 快速上手 －－ 入门Demo，一个简单的IM系统（附源码）&lt;/font&gt;&lt;/a&gt;一文提供的demo的基础上增加文件传送的功能，作为示范，并提供新的demo源码下载，敬请期待！谢谢。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;font color="#0066cc"&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html"&gt;&lt;font color="#0066cc"&gt;&lt;/font&gt;&lt;/a&gt;&lt;/font&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 概述&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="CategoryEntryList1_EntryStoryList_Entries_TitleUrl_7"  href="http://www.cnblogs.com/zhuweisky/archive/2011/03/24/1993417.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 有哪些优点？&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/04/15/2016760.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 版本升级说明（持续更新）&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292821.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 快速上手》系列所有文章&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292831.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 高级进阶》系列所有文章&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/1998857.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/04/20/1998857.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/zhuweisky/archive/2011/04/18/2016743.html</id><title type="text">ESFramework 4.0 快速上手（12） －－ 使用ACK机制发送自定义信息</title><summary type="text">使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法，我们已经可以给服务端或其它在线客户端发送自定义信息了，那么，如何得知接收方是否已经收到了我们发出的信息了呢？特别是针对一些非常重要的信息，确认对方已经收到是非常重要的。ICustomizeInfoOutter接口增加了SendCertainly方法来解决这个问题。</summary><published>2011-04-18T08:47:00Z</published><updated>2011-04-18T08:47:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/18/2016743.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/18/2016743.html"/><content type="html">&lt;p&gt;（本文所介绍的新功能位于&lt;font size="2"&gt;2011.04.18&lt;/font&gt;发布的最新版本中，此次版本变更请参见&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/04/15/2016760.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 版本升级说明（持续更新）&lt;/font&gt;&lt;/a&gt;）&lt;/p&gt;&#xD;
&lt;p&gt;使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send方法，我们已经可以给服务端或其它在线客户端发送自定义信息了，那么，如何得知接收方是否已经收到了我们发出的信息了呢？特别是针对一些非常重要的信息，确认对方已经收到是非常重要的。ICustomizeInfoOutter接口增加了SendCertainly方法来解决这个问题。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-size: 12pt"&gt;&lt;strong&gt;一.启用ACK机制&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;ACK，即确认的意思。当我们发送一个自定义信息给对方时，对方收到信息后，回复一个ACK给我们，我们接收到了ACK，就知道对方一定收到信息了。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img style="width: 299px; height: 153px" border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/zhuweisky/ESF_SendNeedACK.jpg" width="299" height="153" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;ICustomizeInfoOutter接口的SendCertainly方法就是启用了带ACK机制的发送：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;向服务器发送二进制信息，并等待服务器的ACK。当前调用线程会一直阻塞，直到收到ACK；如果超时都没有收到ACK，则将抛出Timeout异常。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;二进制信息&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;SendCertainly(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;informationType,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;info);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;向在线用户targetUserID发送二进制信息，并等待其ACK。当前调用线程会一直阻塞，直到收到ACK；如果超时都没有收到ACK，则将抛出Timeout异常。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="targetUserID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;接收消息的目标用户ID&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;二进制信息&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;SendCertainly(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;targetUserID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;informationType,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;info);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;同样的，服务端ICustomizeInfoController接口的SendCertainly方法，也是启用了带ACK机制的发送：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #808080"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;向ID为userID的在线用户发送二进制信息，并等待其ACK。当前调用线程会一直阻塞，直到收到ACK；如果超时都没有收到ACK，则将抛出Timeout异常。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="userID"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;接收消息的用户ID&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="informationType"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;自定义信息类型&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;param&amp;nbsp;name="info"&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;二进制信息&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;void&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;SendCertainly(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;userID,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;informationType,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;info);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;（1）无论是客户端发送信息给服务端、还是客户端发送信息给其它客户端、或者是服务端发送信息给客户端，它们采用的ACK机制的原理是一样的。&lt;/p&gt;&#xD;
&lt;p&gt;（2）当框架接收到需要ACK的信息时，会自动回复ACK给发送方。这是由ESPlus底层自动完成的，应用程序不需要关心。&lt;/p&gt;&#xD;
&lt;p&gt;（3）ESPlus会先回复ACK，然后才会调用处理信息的方法。所以，当发送方接收到ACK回复时，&lt;span style="color: red"&gt;只是意味着接收方已经接收到了信息&lt;/span&gt;，并不表示接收方已经处理完了信息。&lt;/p&gt;&#xD;
&lt;p&gt;（4）如果接收方在规定的时间内（默认为30秒）都没有收到ACK，则会抛出超时的异常。当然，在规定的时间内没有收到ACK，并不一定就是接收方没有收到信息，而是有几种可能性：&lt;/p&gt;&#xD;
&lt;p&gt;a.由于网络慢，导致ACK延迟抵达发送方。&lt;/p&gt;&#xD;
&lt;p&gt;b.接收方已经掉线。&lt;/p&gt;&#xD;
&lt;p&gt;c.发送方已经掉线。&lt;/p&gt;&#xD;
&lt;p&gt;（5）SendCertainly方法采用的是阻塞模型，即只有收到ACK后才会返回，否则一直阻塞当前调用线程。如果既需要ACK机制的发送，又不希望阻塞当前线程，那么，可以异步调用SendCertainly方法，并通过回调获知是否有超时异常。&lt;/p&gt;&#xD;
&lt;p&gt;（6）ESPlus.Application.CustomizeInfo命名空间下的主要接口的方法已经比较多了，我们这里厘清一下。比如，客户端由ICustomizeInfoOutter接口发出的CommitRequest调用将被服务端ICustomizeInfoBusinessHandler接口的HandleRequest方法来处理，下图我们通过箭头将这些调用与处理关联起来：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img style="width: 696px; height: 354px" border="0" alt="" src="http://images.cnblogs.com/cnblogs_com/zhuweisky/ESF_CallRelation.jpg" width="696" height="354" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;二.具有同样效果的同步调用&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;使用自定义信息，我们还有几个&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/03/21/1990077.html"&gt;&lt;span style="color: #3366ff"&gt;同步调用&lt;/span&gt;&lt;/a&gt;的方法，比如ICustomizeInfoOutter接口的CommitRequest方法和CommitP2PRequest方法、以及ICustomizeInfoController接口的QueryClient方法，这些同步调用的方法都是有返回值的，如果超时没有收到返回的信息，也抛出超时异常。&lt;/p&gt;&#xD;
&lt;p&gt;同步调用与带ACK机制的发送采用的是完全相同的模型，我们完全可以使用同步调用来模拟ACK机制，比如，需要确认的信息就使用同步调用发送，接收方在处理同步调用的时候直接返回null，就可以达到同样的效果。&lt;/p&gt;&#xD;
&lt;p&gt;同步调用与带ACK机制的发送有两点小区别：&lt;/p&gt;&#xD;
&lt;p&gt;（1）在同步调用中，接收方回复的是对应请求的答案；在带ACK机制的发送中，接收方回复的是ACK。&lt;/p&gt;&#xD;
&lt;p&gt;（2）在同步调用中，接收方是处理完信息后才回复；在带ACK机制的发送中，接收方则是先回复ACK，再处理收到信息。&lt;/p&gt;&#xD;
&lt;p&gt;由于同步调用和带ACK机制的发送都有可能超时抛出异常，所以，我们在程序中应当将其try...catch起来，以防止应用程序抛出未被截获的异常。&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;&amp;nbsp;三.在消息骨架流程中挂接ACK机制&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;如果不使用Rapid引擎，而自己来组装消息处理流程，我们就可以直接在&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/03/17/1986727.html"&gt;&lt;span style="color: #3366ff"&gt;消息骨架流程&lt;/span&gt;&lt;/a&gt;上，挂接一个自定义的IMessageSpy，来自动回复那些需要ACK的消息。并且，这种方式的优势在于，我们可以对任意类型的&lt;span style="color: red"&gt;消息&lt;/span&gt;采用ACK机制，而本文介绍的SendCertainly方法只是针对&lt;span style="color: red"&gt;自定义信息&lt;/span&gt;启用ACK机制。当然，对于Rapid引擎的使用者来说，用得最多的也就是自定义信息，所以，也应该足够了。（关于如何让协议类序列化达到最高性能且得到最精简的自定义信息，请参见&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/04/17/2017260.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 快速上手（11） －－ 使用紧凑的序列化器，数倍提升性能&lt;/font&gt;&lt;/a&gt; ）&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 概述&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="CategoryEntryList1_EntryStoryList_Entries_TitleUrl_7"  href="http://www.cnblogs.com/zhuweisky/archive/2011/03/24/1993417.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 有哪些优点？&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/04/15/2016760.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 版本升级说明（持续更新）&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292821.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 快速上手》系列所有文章&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292831.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 高级进阶》系列所有文章&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/2016743.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/04/18/2016743.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/zhuweisky/archive/2011/04/17/2017260.html</id><title type="text">ESFramework 4.0 快速上手（11） －－ 使用紧凑的序列化器，数倍提升性能</title><summary type="text">在分布式通信系统中，网络传递的是二进制流，而内存中是我们基于对象模型构建的各种各样的对象，当我们需要将一个对象通过网络传递给另一个节点时，首先需要将其序列化为字节流，然后通过网络发送给目标节点，目标节点接收后，再反序列化为对象实例。在ESFramework体系中，也是遵循同样的规则。 ESFramework称这些需要经过网络传递的对象称之为协议类（Contract），协议类通常只是一个简单的数据结构封装，用于保存状态的一个哑类（不包含任何方法，从object继承的除外），有点类似于与数据库中表进行映射的贫血Entity。（关于Contract更详细的介绍可以参见ESFramework 4...</summary><published>2011-04-17T11:18:00Z</published><updated>2011-04-17T11:18:00Z</updated><author><name>zhuweisky</name><uri>http://www.cnblogs.com/zhuweisky/</uri></author><link rel="alternate" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/17/2017260.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/zhuweisky/archive/2011/04/17/2017260.html"/><content type="html">&lt;p&gt;在分布式通信系统中，网络传递的是二进制流，而内存中是我们基于对象模型构建的各种各样的对象，当我们需要将一个对象通过网络传递给另一个节点时，首先需要将其序列化为字节流，然后通过网络发送给目标节点，目标节点接收后，再反序列化为对象实例。在ESFramework体系中，也是遵循同样的规则。&lt;/p&gt;&#xD;
&lt;p&gt;ESFramework称这些需要经过网络传递的对象称之为协议类（Contract），协议类通常只是一个简单的数据结构封装，用于保存状态的一个哑类（不包含任何方法，从object继承的除外），有点类似于与数据库中表进行映射的贫血Entity。（关于Contract更详细的介绍可以参见&lt;a id="CategoryEntryList1_EntryStoryList_Entries_TitleUrl_10"  href="http://www.cnblogs.com/zhuweisky/archive/2010/12/24/1915640.html"&gt;&lt;span style="color: #3366ff"&gt;ESFramework 4.0 进阶（01）－－ 消息&lt;/span&gt;&lt;/a&gt;）。基于ESFramework的分布式系统使用这些协议类实例进行数据交换。如果是自己组装骨架流程并使用ESPlus提供的IContractHelper实现，那么ESFramework底层会自动帮我们完成协议对象的序列化和反序列化。&lt;/p&gt;&#xD;
&lt;p&gt;但是，如果我们使用的是Rapid引擎了，我们会经常使用ESPlus.Application.CustomizeInfo.Passive.ICustomizeInfoOutter接口的Send等方法发送二进制自定义信息（实际上，其底层转换为Message、再转换为字节流时，还是由ESFramework自动完成的），这个二进制信息通常是系统中的某个业务对象的序列化结果，而这个序列化过程我们必须自己完成。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;一.序列化方式的两种选择&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;为了将业务对象转换为二进制流，大家通常有两种方案可以选择：使用.NET自带的二进制序列化器，或，先将业务对象转换为字符串（比如xml），再将结果用类似UTF8进行编码得到字节流。 这两种方案都有缺陷。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;1..NET自带的二进制序列化器&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;使用.NET自带的二进制序列化器对我们来说是最方便的，因为只要直接调用API就好了，不需要我们自己动手做任何动作。但是，缺陷也很明显：&lt;/p&gt;&#xD;
&lt;p&gt;（1）首先，能够序列化的类必须加上Serializable标签，且.NET自带的二进制序列化器需要绑定被序列化的类的命名空间和程序集。比方说，将windows里序列化一个协议对象得到的结果传到Silverlight中，是无法完成反序列化的，即使Silverlight中也有完全相同的协议类定义。这也说明，如果通信的客户端是用Silverlight开发的，肯定是不能使用.NET自带的二进制序列化器的。&lt;/p&gt;&#xD;
&lt;p&gt;（2）序列化结果臃肿，其size巨大。在巨大并发高性能的分布式通信系统中，这将降低通信消息，并浪费大量的带宽，是不可忍受的。&lt;/p&gt;&#xD;
&lt;p&gt;（3）效率低下。.NET自带的二进制序列化器基于反射（Relection）的机制工作，比如读取类型的信息、读取/设置字段的值等都是通过反射来完成的。如果每秒仅仅序列化百千个对象，可能还可以应付；但是如果每秒需要序列化几万、甚至几十万个对象，就不堪重负了。&lt;/p&gt;&#xD;
&lt;p&gt;（4）加密困难。由于.NET自带的二进制序列化器在序列化协议对象时，会反射读取对象的内部成员（private），而如果定义协议的dll经过加密后，private成员的名称通常会被混淆成随机的名称，这样就要求通信的各方都使用同一个加密的dll，否则，协议对象的反序列化可能会失败。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;2.通过string进行中转&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;为了解决类似Silverlight客户端与服务端通信的序列化统一的问题，我们可以使用string作为中转，而无论是否为Silverlight环境，对同一字符串进行相同格式（如UTF8）的编码，得到的字节流肯定是一样的。反过来，同样的字节流在不同的环境中使用相同的解码器进行解码得到的字符串也一样。这是一种可行的方案，但是缺点也是有的：&lt;/p&gt;&#xD;
&lt;p&gt;（1）我们需要自己打造协议对象与字符串之间的相互转换 -- 这可能是一个费时费神的又容易出错的工作。&lt;/p&gt;&#xD;
&lt;p&gt;（2）序列化之后的结果的Size取决于我们协议对象与字符串之间相互转换时所采用的规则，同样也取决于我们的耐心程度 -- 为了使结果的Size更小，我们也许要动更多的脑筋。&lt;/p&gt;&#xD;
&lt;p&gt;当然，现在也有现成的将对象与字符串想换转换的工具，比如JSON和XML。就一般而言，使用JSON转换协议对象得到的结果比使用xml要小很多。&lt;/p&gt;&#xD;
&lt;p&gt;（3）同.NET自带的二进制序列化器，对象属性值的读取/设置、对象的创建等通常也是基于反射的，所以，效率同样存在问题。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;二.第三种方案&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;ESPlus提供了更紧凑、且不需绑定命名空间和程序集的二进制序列化器：ESPlus.Serialization.&lt;span style="color: #008080"&gt;CompactPropertySerializer。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;（1）CompactPropertySerializer 基于Emit技术和缓存技术构建，且避免了反射带来的开销，所以效率大大提升。&lt;/p&gt;&#xD;
&lt;p&gt;（2）CompactPropertySerializer 内部使用了简练、紧凑的序列化格式和规则，使得序列化的结果Size更短小。&lt;/p&gt;&#xD;
&lt;p&gt;（3）将被序列化的类不需要增加任何标签，且不依赖于命名空间和程序集，只要类的定义完全一致，CompactPropertySerializer 就可以正常工作。真正的弱侵入性。&lt;/p&gt;&#xD;
&lt;p&gt;（4）ESFramework.SL也提供了完全一样的CompactPropertySerializer ，所以基于第3点，服务端与Silverlight客户端就可以协同工作了。 &lt;/p&gt;&#xD;
&lt;p&gt;（5）只要采用CompactPropertySerializer的序列化格式，.NET服务端可以与任何其它语言（如C++、JAVA等）构建的客户端协同工作。&lt;/p&gt;&#xD;
&lt;p&gt;CompactPropertySerializer解决了前面提出的几个问题，当然，它也不是全能的，使用它也有一些限制，下面我们即将讲到。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;三.如何使用CompactPropertySerializer &lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;ESPlus.Serialization.&lt;span style="color: #008080"&gt;CompactPropertySerializer &lt;/span&gt;和 ESFramework.SL.Serialization.&lt;span style="color: #008080"&gt;CompactPropertySerializer &lt;/span&gt;是ESFramework提供的分别用于桌面应用和Sivlerlight客户端的二进制序列化器。它们的实现几乎一模一样，所以，使用时要注意的方面也是相同的：&lt;/p&gt;&#xD;
&lt;p&gt;（1）CompactPropertySerializer 支持类和结构的序列化，但是被序列化的类或结构必须有默认的构造函数（Ctor）。&lt;/p&gt;&#xD;
&lt;p&gt;（2）CompactPropertySerializer 只序列化那些&lt;span style="color: #ff0000"&gt;可读写&lt;/span&gt;的属性，如果一个属性仅仅是只读或只写的，那么该属性不会被序列化。这也是Compact&lt;span style="color: #ff0000"&gt;Property&lt;/span&gt;Serializer名称中Property的含义。 &lt;/p&gt;&#xD;
&lt;p&gt;（3）CompactPropertySerializer 支持的类型：基础数据类型(如int、long、bool等)、string、byte[]，以及由这些类型构成的class或struct。&lt;/p&gt;&#xD;
&lt;p&gt;（4）支持多层嵌套 -- 即被序列化的class中可以包含别的类型的对象，只要每一个被嵌入的对象最后都是由基础数据类型构成的。&lt;/p&gt;&#xD;
&lt;p&gt;（5）除byte[]/List&amp;lt;&amp;gt;/Dictionary&amp;lt;,&amp;gt;泛型外，不支持其它的集合类型。&amp;nbsp; &lt;/p&gt;&#xD;
&lt;p&gt;（6）不支持循环引用。如果存在循环引用，序列化时将导致死循环。&lt;/p&gt;&#xD;
&lt;p&gt;正如本文开始提到的，在通信系统中用到的协议类都是一些最简单的仅仅包含数据的&amp;#8220;哑类&amp;#8221;，所以，上面的限制对我们在设计协议类时是没有什么约束的。尽可能地使用简单的数据类型，然后将需要序列化的字段通过可读写的属性暴露就OK了。&lt;/p&gt;&#xD;
&lt;p&gt;CompactPropertySerializer 包括了序列化和反序列化的两个基本方法：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;Serialize&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;T&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(T&amp;nbsp;obj);&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; T&amp;nbsp;Deserialize&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;T&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;buff,&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;startIndex)&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;where&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;T&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;方法含义很明显，不解释了。另外，CompactPropertySerializer 采用了Singleton，我们可以在程序中直接使用这个Singleton&amp;nbsp;，通过CompactPropertySerializer.&lt;span style="color: #ff0000"&gt;Default&lt;/span&gt;属性获得该Singleton实例的引用。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong style="font-size: 12pt"&gt;四.试试CompactPropertySerializer的性能和效率 &lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们以文件传送中要使用到的协议类BeginSendFileContract为例，BeginSendFileContract定义如下：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('682c9982-f72d-4b6c-a9bc-85b43030a458')"&gt;&lt;img style="display: none" id="code_img_opened_682c9982-f72d-4b6c-a9bc-85b43030a458"  onclick="cnblogs_code_hide('682c9982-f72d-4b6c-a9bc-85b43030a458',event)" src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif"&gt;&#xD;
&lt;div id="cnblogs_code_open_682c9982-f72d-4b6c-a9bc-85b43030a458" &gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Serializable]&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;BeginSendFileContract&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#region&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;OriginFilePath&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;originFilePath;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;发送方发送的文件的全路径。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;OriginFilePath&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;get&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;originFilePath;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;set&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&amp;nbsp;originFilePath&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;value;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#endregion&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#region&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileLength&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;long&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileLength&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;long&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileLength&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;get&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.fileLength&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;set&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.fileLength&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;value&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#endregion&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#region&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;LastUpdateTime&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;DateTime&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;lastUpdateTime;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;被发送的文件最后一次更新时间。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;DateTime&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;LastUpdateTime&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;get&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;lastUpdateTime;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;set&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&amp;nbsp;lastUpdateTime&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;value;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#endregion&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#region&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileID&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;fileID&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800000"&gt;""&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;FileID&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;get&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.fileID&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;set&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;&lt;span style="color: #000000"&gt;.fileID&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;value&amp;nbsp;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#endregion&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#region&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Comment&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;comment&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;&lt;span style="color: #000000"&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;span style="color: #008000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;Comment&amp;nbsp;用于存储与本次文件发送相关的额外附加信息。比如，在类似ftp的上传文件的服务中，Comment的内容可以是服务器保存上传文件的路径。&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;///&lt;/span&gt;&lt;span style="color: #008000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #808080"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: #808080"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;Comment&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;get&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;comment;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;set&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;{&amp;nbsp;comment&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;value;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;#endregion&lt;/span&gt;&lt;span style="color: #000000"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;之所以加上[Serializable]标签，是因为下面测试.NET自带的二进制序列化器需要用到，正式的BeginSendFileContract定义是没有这个标签的。&lt;/p&gt;&#xD;
&lt;p&gt;正如大多数的协议类一样，这个类仅仅包含几个简单类型的属性，现在我们来对比一下.NET自带的二进制序列化器与CompactPropertySerializer的表现。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;（1）比较序列化结果的大小：&amp;nbsp;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #008080"&gt;BeginSendFileContract&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;contract&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;BeginSendFileContract&lt;/span&gt;&lt;span style="color: #000000"&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;result1&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CompactPropertySerializer&lt;/span&gt;&lt;span style="color: #000000"&gt;.Default.Serialize&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;BeginSendFileContract&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(contract);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;result2&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;ESBasic.Helpers.&lt;/span&gt;&lt;span style="color: #008080"&gt;SerializeHelper&lt;/span&gt;&lt;span style="color: #000000"&gt;.SerializeObject(contract);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;ESBasic.Helpers.SerializeHelper就是对.NET自带的二进制序列化器的简化封装。执行的结果如下：&lt;/p&gt;&#xD;
&lt;p&gt;result1的长度为：&lt;strong style="color: #ff0000"&gt;32&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;result2的长度为：&lt;strong style="color: #ff0000"&gt;242&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;.Net自带序列化器的结果是CompactPropertySerializer结果的7-8倍，如果为contract的一些string类型的字段赋有意义的值，这个倍数会稍微降一点；如果这个contract的定义包含了更多的要序列化的属性，那么这个倍数还会继续提高。不管怎么样，这个比例都是很吓人的，所以在高频的通信系统中，相比于使用.Net自带序列化器，采用CompactPropertySerializer可以节省大量的带宽。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;（2）测试性能：&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们分别运行两个序列化100万次，看所要的时间：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: #008080"&gt;BeginSendFileContract&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;contract&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;BeginSendFileContract&lt;/span&gt;&lt;span style="color: #000000"&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;Stopwatch&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;stopwatch&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;Stopwatch&lt;/span&gt;&lt;span style="color: #000000"&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stopwatch.Start();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;1000000&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;i&lt;/span&gt;&lt;span style="color: #000000"&gt;++&lt;/span&gt;&lt;span style="color: #000000"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;result1&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #008080"&gt;CompactPropertySerializer&lt;/span&gt;&lt;span style="color: #000000"&gt;.Default.Serialize&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #008080"&gt;BeginSendFileContract&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000"&gt;(contract);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stopwatch.Stop();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;span1&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;stopwatch.ElapsedMilliseconds;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stopwatch.Reset();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stopwatch.Start();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;(&lt;/span&gt;&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;0&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;i&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #800080"&gt;1000000&lt;/span&gt;&lt;span style="color: #000000"&gt;;&amp;nbsp;i&lt;/span&gt;&lt;span style="color: #000000"&gt;++&lt;/span&gt;&lt;span style="color: #000000"&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;&lt;span style="color: #000000"&gt;[]&amp;nbsp;result2&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;ESBasic.Helpers.&lt;/span&gt;&lt;span style="color: #008080"&gt;SerializeHelper&lt;/span&gt;&lt;span style="color: #000000"&gt;.SerializeObject(contract);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stopwatch.Stop();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;double&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;span2&amp;nbsp;&lt;/span&gt;&lt;span style="color: #000000"&gt;=&lt;/span&gt;&lt;span style="color: #000000"&gt;&amp;nbsp;stopwatch.ElapsedMilliseconds;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&#xD;
&lt;p&gt;运行结果如下：&lt;/p&gt;&#xD;
&lt;p&gt;span1：&lt;strong style="color: #ff0000"&gt;5324&lt;/strong&gt;ms&lt;/p&gt;&#xD;
&lt;p&gt;span2：&lt;span style="color: #ff0000"&gt;&lt;strong&gt;17249&lt;/strong&gt;&lt;/span&gt;ms&lt;/p&gt;&#xD;
&lt;p&gt;CompactPropertySerializer比.Net自带的序列化器快3倍以上，优势不言而喻。&lt;/p&gt;&#xD;
&lt;p&gt;大家可以参考上面的demo，写更多的测试程序，来测试更多的内容，包括它们在反序列化方面的表现的比较。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;对于一般的通信应用，使用.Net自带的二进制序列化器也许就够用了，不会有太大的影响，但是如果在类似MMORPG、视频/音频会议等等需要高频、高性能的通信系统中，.Net自带的二进制序列化器就不是最好的选择了。如果使用ESFramework来构建你的分布式通信应用，那就可以从CompactPropertySerializer得到更多的帮助。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html"&gt;&lt;font color="#0066cc"&gt;&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 概述&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="CategoryEntryList1_EntryStoryList_Entries_TitleUrl_7"  href="http://www.cnblogs.com/zhuweisky/archive/2011/03/24/1993417.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 有哪些优点？&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a id="ctl02_TitleUrl"  href="http://www.cnblogs.com/zhuweisky/archive/2011/04/15/2016760.html"&gt;&lt;font color="#0066cc"&gt;ESFramework 4.0 版本升级说明（持续更新）&lt;/font&gt;&lt;/a&gt; &lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292821.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 快速上手》系列所有文章&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/category/292831.html"&gt;&lt;span style="color: #3366ff"&gt;《ESFramework 4.0 高级进阶》系列所有文章&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/zhuweisky/aggbug/2017260.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhuweisky/archive/2011/04/17/2017260.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
