﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Chan Chen Coding...-文章分类-Netty</title><link>http://www.blogjava.net/czihong/category/53023.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 24 Jan 2013 09:28:21 GMT</lastBuildDate><pubDate>Thu, 24 Jan 2013 09:28:21 GMT</pubDate><ttl>60</ttl><item><title>Netty 4.0 源码分析（八）：Netty 4.0中的io.netty.buffer包</title><link>http://www.blogjava.net/czihong/articles/392059.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Tue, 27 Nov 2012 03:34:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/392059.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/392059.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/392059.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/392059.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/392059.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Netty 4.0的源码结构与之前的3.X版本发生了较大的变化，以下是Netty 4.0源码的层次结构  netty/  &nbsp;&nbsp; common/&nbsp;&nbsp;&nbsp;&nbsp; - utility and logging  &nbsp;&nbsp; buffer/&nbsp;&nbsp;&nbsp;&nbsp; - buffer API  &nbsp;&nbsp;...&nbsp;&nbsp;<a href='http://www.blogjava.net/czihong/articles/392059.html'>阅读全文</a><img src ="http://www.blogjava.net/czihong/aggbug/392059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-11-27 11:34 <a href="http://www.blogjava.net/czihong/articles/392059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netty 4.0 源码分析（七）：AbstractBootstrap抽象类</title><link>http://www.blogjava.net/czihong/articles/391953.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Mon, 26 Nov 2012 02:57:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/391953.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/391953.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/391953.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/391953.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/391953.html</trackback:ping><description><![CDATA[<p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">是一个帮助类，通过方法链（</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">）的方式，提供了一个简单易用的方式来配置</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Bootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">，然后启动一个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">。在理解</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Netty</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">源码中的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;"> ServerBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">和</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Bootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">之前，应该先了解一下什么是</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">。<br /></span></p>  <p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;"><br />Wiki</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">上面对于</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">的定义如下：</span></p>  <p><strong><span style="font-size: 6.5pt; font-family: 'Courier New'; background-color: white; background-position: initial initial; background-repeat: initial initial;">Method chaining</span></strong><span style="font-size: 6.5pt; font-family: 'Courier New'; background-color: white; background-position: initial initial; background-repeat: initial initial;">, is a common technique for invoking multiple method calls in object-oriented programming languages</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;"><span style="background-color: white; background-position: initial initial; background-repeat: initial initial;">. Each method returns an object (possibly the current object itself), allowing the calls to be chained together in a single statement.</span></span></p>  <p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">在面向对象的编程语言中，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">是一种用于调用多个方法的常用技术。每个方法都会返回一个对象（可能是当前对象本身），这样做的好处就是，通过一条语句，就可以讲所有的方法调用链接在一起。</span>&nbsp;</p>  <p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;"><br />定义有一些抽象，那么可以通过实际的例子来进行理解和消化。</span></p>  <p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">假设有一个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">StringBuffer</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">的类，类中有一个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">append()</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">方法</span></p>  <p align="left"></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;StringBuffer&nbsp;{<br />&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;append(String&nbsp;str)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />&nbsp;useful&nbsp;code&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;}<br />}</div><p>&nbsp;</p>  <p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">这个类有缺点就是说，在向</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">StringBuffer</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">对象追加新的字符串的时候，需要在多条语句中，不断的调用</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">append()</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">方法。</span></p>  <pre><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->StringBuffer&nbsp;sb&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;StringBuffer();<br />sb.append("Hello&nbsp;");<br />sb.append(name);<br />sb.append("!&nbsp;Welcome!");</div></pre>  <p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">而</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">的实现，就可以避免这个缺陷。</span></p>  <pre><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;StringBuffer&nbsp;{<br />&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;StringBuffer&nbsp;append(String&nbsp;str)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />&nbsp;useful&nbsp;code&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">this</span>;<br />&nbsp;&nbsp;}<br />}</div></pre>  <p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">现在我们就可以再一条语句中实现第一个例子的功能了。</span></p>  <pre><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->StringBuffer&nbsp;sb&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;StringBuffer();<br />sb.append("Hello&nbsp;").append(name).append("!&nbsp;Welcome!");</div></pre>  <p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;"><br />AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">抽象类</span> <span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">（部分代码）</span></p>  <p align="left"></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">package</span>&nbsp;io.netty.bootstrap;<br />&nbsp;<br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">abstract</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;AbstractBootstrap&lt;B&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;AbstractBootstrap&lt;?&gt;&gt;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;EventLoopGroup&nbsp;group;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;ChannelFactory&nbsp;factory;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;SocketAddress&nbsp;localAddress;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;Map&lt;ChannelOption&lt;?&gt;,&nbsp;Object&gt;&nbsp;options&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LinkedHashMap&lt;ChannelOption&lt;?&gt;,&nbsp;Object&gt;();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;Map&lt;AttributeKey&lt;?&gt;,&nbsp;Object&gt;&nbsp;attrs&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LinkedHashMap&lt;AttributeKey&lt;?&gt;,&nbsp;Object&gt;();<br /><span style="color: #0000FF; ">private</span>&nbsp;ChannelHandler&nbsp;handler;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;@SuppressWarnings("unchecked")<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;B&nbsp;group(EventLoopGroup&nbsp;group)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(group&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NullPointerException("group");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(<span style="color: #0000FF; ">this</span>.group&nbsp;!=&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;IllegalStateException("group&nbsp;set&nbsp;already");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.group&nbsp;=&nbsp;group;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(B)&nbsp;<span style="color: #0000FF; ">this</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;B&nbsp;channel(Class&lt;?&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;Channel&gt;&nbsp;channelClass)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(channelClass&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NullPointerException("channelClass");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;channelFactory(<span style="color: #0000FF; ">new</span>&nbsp;BootstrapChannelFactory(channelClass));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;@SuppressWarnings("unchecked")<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;B&nbsp;channelFactory(ChannelFactory&nbsp;factory)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(factory&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NullPointerException("factory");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(<span style="color: #0000FF; ">this</span>.factory&nbsp;!=&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;IllegalStateException("factory&nbsp;set&nbsp;already");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.factory&nbsp;=&nbsp;factory;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(B)&nbsp;<span style="color: #0000FF; ">this</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;@SuppressWarnings("unchecked")<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;B&nbsp;localAddress(SocketAddress&nbsp;localAddress)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.localAddress&nbsp;=&nbsp;localAddress;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(B)&nbsp;<span style="color: #0000FF; ">this</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;@SuppressWarnings("unchecked")<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;&lt;T&gt;&nbsp;B&nbsp;option(ChannelOption&lt;T&gt;&nbsp;option,&nbsp;T&nbsp;value)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(option&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NullPointerException("option");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(value&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.remove(option);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.put(option,&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(B)&nbsp;<span style="color: #0000FF; ">this</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;&lt;T&gt;&nbsp;B&nbsp;attr(AttributeKey&lt;T&gt;&nbsp;key,&nbsp;T&nbsp;value)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(key&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NullPointerException("key");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(value&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attrs.remove(key);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attrs.put(key,&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(B)&nbsp;<span style="color: #0000FF; ">this</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;@SuppressWarnings("unchecked")<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;B&nbsp;handler(ChannelHandler&nbsp;handler)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(handler&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NullPointerException("handler");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.handler&nbsp;=&nbsp;handler;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(B)&nbsp;<span style="color: #0000FF; ">this</span>;<br />&nbsp; &nbsp; }<br />}</div><p>&nbsp;</p>  <p align="left">&nbsp;</p>  <p align="left"><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">声明了六个私有的成员变量，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">EventLoopGroup</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">对象，</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">ChannelFacotry</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">对象，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">SockteAddress</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">对象，</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">Map&lt;ChannelOption&lt;?&gt;,Object&gt;</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">对象，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">Map&lt;Attribute&lt;?&gt;,Object&gt;</span><span style="font-size:6.5pt; font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">对象，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">ChannelHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">对象。并且有相对应的方法，来设置这些对象，如</span></p>  <p align="left"></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;B&nbsp;group(EventLoopGroup&nbsp;group)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(group&nbsp;==&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NullPointerException("group");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(<span style="color: #0000FF; ">this</span>.group&nbsp;!=&nbsp;<span style="color: #0000FF; ">null</span>)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;IllegalStateException("group&nbsp;set&nbsp;already");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.group&nbsp;=&nbsp;group;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;(B)&nbsp;<span style="color: #0000FF; ">this</span>;<br />}</div><p>&nbsp;</p>  <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">通过传进来的</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">group</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">对象，然后将</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">中的</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">group</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">指向传进来的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">group</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">。最终返回的还是</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">这个当前对象。</span></p>  <p align="left">&nbsp;</p>  <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">六个对象的作用</span></p>  <table border="1" cellspacing="0" cellpadding="0" style="border-collapse: collapse; border: none;">  <tbody><tr>   <td width="284" valign="top" style="width: 213.05pt; border: 1pt solid black; padding: 0cm 5.4pt;">   <p align="left"><span style="font-size:6.5pt;font-family:   &quot;Courier New&quot;;">EventLoopGroup group</span></p>   </td>   <td width="284" valign="top" style="width: 213.05pt; border-style: solid solid solid none; border-top-color: black; border-right-color: black; border-bottom-color: black; border-top-width: 1pt; border-right-width: 1pt; border-bottom-width: 1pt; padding: 0cm 5.4pt;">   <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">用于处理将要被创建的所有</span><span style="font-size:   6.5pt;font-family:&quot;Courier New&quot;;">event</span></p>   </td>  </tr>  <tr>   <td width="284" valign="top" style="width: 213.05pt; border-style: none solid solid; border-right-color: black; border-bottom-color: black; border-left-color: black; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt;">   <p align="left"><span style="font-size:6.5pt;font-family:   &quot;Courier New&quot;;">ChannelFactory factory</span></p>   </td>   <td width="284" valign="top" style="width:213.05pt;border-top:none;border-left:   none;border-bottom:solid black 1.0pt;   border-right:solid black 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">建立一个工厂，用于以后的</span><span style="font-size:   6.5pt;font-family:&quot;Courier New&quot;;">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">创建</span></p>   </td>  </tr>  <tr>   <td width="284" valign="top" style="width: 213.05pt; border-style: none solid solid; border-right-color: black; border-bottom-color: black; border-left-color: black; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt;">   <p align="left"><span style="font-size:6.5pt;font-family:   &quot;Courier New&quot;;">SocketAddress localAddress;</span></p>   </td>   <td width="284" valign="top" style="width:213.05pt;border-top:none;border-left:   none;border-bottom:solid black 1.0pt;   border-right:solid black 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">用于绑定本地的网络地址</span></p>   </td>  </tr>  <tr>   <td width="284" valign="top" style="width: 213.05pt; border-style: none solid solid; border-right-color: black; border-bottom-color: black; border-left-color: black; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt;">   <p align="left"><span style="font-size:6.5pt;font-family:   &quot;Courier New&quot;;">Map&lt;ChannelOption&lt;?&gt;, Object&gt;   options</span></p>   </td>   <td width="284" valign="top" style="width:213.05pt;border-top:none;border-left:   none;border-bottom:solid black 1.0pt;   border-right:solid black 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">指定所创建</span><span style="font-size:6.5pt;   font-family:&quot;Courier New&quot;;">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">的选项，如</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">TCP_NODELAY</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">，</span><span style="font-size:6.5pt;   font-family:&quot;Courier New&quot;;">AIO_READ_TIMEOUT</span></p>   </td>  </tr>  <tr>   <td width="284" valign="top" style="width: 213.05pt; border-style: none solid solid; border-right-color: black; border-bottom-color: black; border-left-color: black; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt;">   <p align="left"><span style="font-size:6.5pt;font-family:   &quot;Courier New&quot;;">Map&lt;AttributeKey&lt;?&gt;, Object&gt;   attrs</span></p>   </td>   <td width="284" valign="top" style="width:213.05pt;border-top:none;border-left:   none;border-bottom:solid black 1.0pt;   border-right:solid black 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">指定所创建</span><span style="font-size:6.5pt;   font-family:&quot;Courier New&quot;;">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">的属性</span></p>   </td>  </tr>  <tr>   <td width="284" valign="top" style="width: 213.05pt; border-style: none solid solid; border-right-color: black; border-bottom-color: black; border-left-color: black; border-right-width: 1pt; border-bottom-width: 1pt; border-left-width: 1pt; padding: 0cm 5.4pt;">   <p align="left"><span style="font-size:6.5pt;font-family:   &quot;Courier New&quot;;">ChannelHandler handler</span></p>   </td>   <td width="284" valign="top" style="width:213.05pt;border-top:none;border-left:   none;border-bottom:solid black 1.0pt;   border-right:solid black 1.0pt;padding:0cm 5.4pt 0cm 5.4pt">   <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">用于处理各类请求</span></p>   </td>  </tr> </tbody></table>  <p align="left">&nbsp;</p>  <p align="left"><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">抽象类的接口<br /></span></p><p>&nbsp;</p>  <p align="center" style="text-align:center;text-autospace:none"><img src="http://www.blogjava.net/images/blogjava_net/czihong/AbstractBootstrap抽象类UML图.JPG" border="0" alt="" /><br /></p>  <p align="center" style="text-align:center;text-autospace:none"><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">抽象类</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">UML</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">图</span></p>  <p align="left">&nbsp;</p>  <p align="left"><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;">ServerBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">和</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">Bootstrap</span></p>  <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">在</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">Netty 4.0</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">中，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">ServerBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">用于为服务器启动</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">ServerChannel</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">Bootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">用于为客服端启动</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">。这两个类是</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">的具体实现。<br /><br /></span></p><div>备注:因为笔者开始写Netty源码分析的时候，Netty 4.0还是处于Alpha阶段，之后的API可能还会有改动，笔者将会及时更改。使用开源已经有好几年的时间了，一直没有时间和精力来具体研究某个开源项目的具体实现，这次是第一次写开源项目的源码分析，如果文中有错误的地方，欢迎读者可以留言指出。对于转载的读者，请注明文章的出处。</div><div>希望和广大的开发者/开源爱好者进行交流，欢迎大家的留言和讨论。</div><p>&nbsp;</p><img src ="http://www.blogjava.net/czihong/aggbug/391953.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-11-26 10:57 <a href="http://www.blogjava.net/czihong/articles/391953.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netty 4.0 源码分析（六）：EventLoop和EventLoopGroup</title><link>http://www.blogjava.net/czihong/articles/391939.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sun, 25 Nov 2012 13:49:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/391939.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/391939.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/391939.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/391939.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/391939.html</trackback:ping><description><![CDATA[<p align="left"><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;">EventLoop</span><span style="font-size: 6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">相当于一个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">Thread</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">线程，而</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">EventLoopGroup</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">则是管理这些</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">EventLoop</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">的</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">Thread</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">线程池</span></p>  <p align="left"><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;">EventLoop</span><span style="font-size: 6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">接口</span></p>  <p align="left"></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">package</span>&nbsp;io.netty.channel;<br /><br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">interface</span>&nbsp;EventLoop&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;EventExecutor,&nbsp;EventLoopGroup&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;EventLoopGroup&nbsp;parent();<br />}</div>  <p align="center" style="text-align:center;text-autospace:none"><img src="http://www.blogjava.net/images/blogjava_net/czihong/EventLoop接口UML图.JPG" border="0" alt="" width="343" height="231" /><br /></p>  <p align="center" style="text-align:center;text-autospace:none"><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;">EventLoop</span><span style="font-size: 6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">接口</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">UML</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">图</span></p>  <p align="left"><em><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;">parent()</span><span style="font-size:6.5pt; font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">方法</span></em></p>  <p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;">返回管理这个</span><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;">EventLoop</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;">的</span><span style="font-size: 6.5pt;font-family:&quot;Courier New&quot;">EventLoopGroup</span><span style="font-size: 6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;">。</span></p>  <p><br /></p>  <p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">EventLoopGroup</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;">接口</span></p>  <p align="left"></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">package</span>&nbsp;io.netty.channel;<br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">interface</span>&nbsp;EventLoopGroup&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;EventExecutorGroup&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;EventLoop&nbsp;next();<br />&nbsp;&nbsp;&nbsp;&nbsp;ChannelFuture&nbsp;register(Channel&nbsp;channel);<br />&nbsp;&nbsp;&nbsp;&nbsp;ChannelFuture&nbsp;register(Channel&nbsp;channel,&nbsp;ChannelFuture&nbsp;future);<br />}</div>  <p align="center" style="text-align:center"><img src="http://www.blogjava.net/images/blogjava_net/czihong/EventLoopGroup接口UML图.JPG" border="0" alt="" width="603" height="250" /><br /></p>  <p align="center" style="text-align:center"><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">EventLoopGroup</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;">接口</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">UML</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;">图</span></p>  <p align="left">&nbsp;</p>  <p align="left"><em><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">next()</span></em></p>  <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">返回下一个</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">EventLoop<br /><br /></span></p>  <p align="left"><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;"><em>register(Channel channel)</em></span></p>  <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">指定一个</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">EventLoopGroup</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Lucida Console&quot;;Courier New&quot;;">来注册某个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">Channel</span><span style="font-size: 6.5pt; font-family: 宋体;">。<br /><br /></span><div>备注:因为笔者开始写Netty源码分析的时候，Netty 4.0还是处于Alpha阶段，之后的API可能还会有改动，笔者将会及时更改。使用开源已经有好几年的时间了，一直没有时间和精力来具体研究某个开源项目的具体实现，这次是第一次写开源项目的源码分析，如果文中有错误的地方，欢迎读者可以留言指出。对于转载的读者，请注明文章的出处。</div><div>希望和广大的开发者/开源爱好者进行交流，欢迎大家的留言和讨论。</div></p><img src ="http://www.blogjava.net/czihong/aggbug/391939.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-11-25 21:49 <a href="http://www.blogjava.net/czihong/articles/391939.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netty 4.0 源码分析（四）：ByteBuf</title><link>http://www.blogjava.net/czihong/articles/391937.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sun, 25 Nov 2012 12:44:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/391937.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/391937.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/391937.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/391937.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/391937.html</trackback:ping><description><![CDATA[<p><span style="font-size: 6.5pt; font-family: 'Courier New';">Netty</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">是基于流的消息传递机制。</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Netty</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">框架中，所有消息的传输都依赖于</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ByteBuf</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">接口，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ByteBuf</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">是</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Netty NIO</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">框架中的缓冲区。</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ByteBuf</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">接口可以理解为一般的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Byte</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">数组，不过</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Netty</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">对</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Byte</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">进行了封装，增加了一些实用的方法。</span></p>  <p><br /></p>  <p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelBuf</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">接口</span></p>  <p align="left"></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">package</span>&nbsp;io.netty.buffer;<br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">interface</span>&nbsp;ChannelBuf&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;ChannelBufType&nbsp;type();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;isPooled();<br />}</div><p><br /></p>  <p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ByteBuf</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">接口</span>&nbsp;</p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">package</span>&nbsp;io.netty.buffer;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.io.IOException;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.io.InputStream;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.io.OutputStream;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.nio.ByteBuffer;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.nio.ByteOrder;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.nio.channels.GatheringByteChannel;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.nio.channels.ScatteringByteChannel;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.nio.charset.Charset;<br /><span style="color: #0000FF; ">import</span>&nbsp;java.nio.charset.UnsupportedCharsetException;<br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">interface</span>&nbsp;ByteBuf&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;ChannelBuf,&nbsp;Comparable&lt;ByteBuf&gt;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;capacity();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;capacity(<span style="color: #0000FF; ">int</span>&nbsp;newCapacity);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;maxCapacity();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteOrder&nbsp;order();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;order(ByteOrder&nbsp;endianness);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;isDirect();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;readerIndex();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readerIndex(<span style="color: #0000FF; ">int</span>&nbsp;readerIndex);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;writerIndex();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writerIndex(<span style="color: #0000FF; ">int</span>&nbsp;writerIndex);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setIndex(<span style="color: #0000FF; ">int</span>&nbsp;readerIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;writerIndex);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;readableBytes();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;writableBytes();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;readable();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;writable();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;clear();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;markReaderIndex();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;resetReaderIndex();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;markWriterIndex();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;resetWriterIndex();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;discardReadBytes();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;ensureWritableBytes(<span style="color: #0000FF; ">int</span>&nbsp;minWritableBytes);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;ensureWritableBytes(<span style="color: #0000FF; ">int</span>&nbsp;minWritableBytes,&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;force);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;getBoolean(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">byte</span>&nbsp;&nbsp;getByte(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">short</span>&nbsp;getUnsignedByte(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">short</span>&nbsp;getShort(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;getUnsignedShort(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;getMedium(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;getUnsignedMedium(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;getInt(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">long</span>&nbsp;&nbsp;getUnsignedInt(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">long</span>&nbsp;&nbsp;getLong(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;&nbsp;getChar(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">float</span>&nbsp;getFloat(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">double</span>&nbsp;getDouble(<span style="color: #0000FF; ">int</span>&nbsp;index);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;getBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;ByteBuf&nbsp;dst);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;getBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;ByteBuf&nbsp;dst,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;getBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;ByteBuf&nbsp;dst,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;dstIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;getBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">byte</span>[]&nbsp;dst);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;getBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">byte</span>[]&nbsp;dst,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;dstIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;getBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;ByteBuffer&nbsp;dst);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;getBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;OutputStream&nbsp;out,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;getBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;GatheringByteChannel&nbsp;out,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException;<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setBoolean(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setByte(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setShort(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setMedium(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setInt(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setLong(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">long</span>&nbsp;&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setChar(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setFloat(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">float</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setDouble(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">double</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;ByteBuf&nbsp;src);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;ByteBuf&nbsp;src,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;ByteBuf&nbsp;src,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;srcIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">byte</span>[]&nbsp;src);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">byte</span>[]&nbsp;src,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;srcIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;ByteBuffer&nbsp;src);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;setBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;InputStream&nbsp;in,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;setBytes(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;ScatteringByteChannel&nbsp;in,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException;<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;setZero(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;readBoolean();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">byte</span>&nbsp;&nbsp;readByte();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">short</span>&nbsp;readUnsignedByte();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">short</span>&nbsp;readShort();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;readUnsignedShort();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;readMedium();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;readUnsignedMedium();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;readInt();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">long</span>&nbsp;&nbsp;readUnsignedInt();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">long</span>&nbsp;&nbsp;readLong();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;&nbsp;readChar();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">float</span>&nbsp;readFloat();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">double</span>&nbsp;readDouble();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readBytes(<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readSlice(<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readBytes(ByteBuf&nbsp;dst);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readBytes(ByteBuf&nbsp;dst,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readBytes(ByteBuf&nbsp;dst,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;dstIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readBytes(<span style="color: #0000FF; ">byte</span>[]&nbsp;dst);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readBytes(<span style="color: #0000FF; ">byte</span>[]&nbsp;dst,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;dstIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readBytes(ByteBuffer&nbsp;dst);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;readBytes(OutputStream&nbsp;out,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;readBytes(GatheringByteChannel&nbsp;out,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException;<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;skipBytes(<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeBoolean(<span style="color: #0000FF; ">boolean</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeByte(<span style="color: #0000FF; ">int</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeShort(<span style="color: #0000FF; ">int</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeMedium(<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeInt(<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeLong(<span style="color: #0000FF; ">long</span>&nbsp;&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeChar(<span style="color: #0000FF; ">int</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeFloat(<span style="color: #0000FF; ">float</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeDouble(<span style="color: #0000FF; ">double</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeBytes(ByteBuf&nbsp;src);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeBytes(ByteBuf&nbsp;src,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeBytes(ByteBuf&nbsp;src,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;srcIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeBytes(<span style="color: #0000FF; ">byte</span>[]&nbsp;src);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeBytes(<span style="color: #0000FF; ">byte</span>[]&nbsp;src,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;srcIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeBytes(ByteBuffer&nbsp;src);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;writeBytes(InputStream&nbsp;in,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;&nbsp;writeBytes(ScatteringByteChannel&nbsp;in,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;IOException;<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;writeZero(<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;indexOf(<span style="color: #0000FF; ">int</span>&nbsp;fromIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;toIndex,&nbsp;<span style="color: #0000FF; ">byte</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;indexOf(<span style="color: #0000FF; ">int</span>&nbsp;fromIndex,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;toIndex,&nbsp;ByteBufIndexFinder&nbsp;indexFinder);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;bytesBefore(<span style="color: #0000FF; ">byte</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;bytesBefore(ByteBufIndexFinder&nbsp;indexFinder);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;bytesBefore(<span style="color: #0000FF; ">int</span>&nbsp;length,&nbsp;<span style="color: #0000FF; ">byte</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;bytesBefore(<span style="color: #0000FF; ">int</span>&nbsp;length,&nbsp;ByteBufIndexFinder&nbsp;indexFinder);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;bytesBefore(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length,&nbsp;<span style="color: #0000FF; ">byte</span>&nbsp;value);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;bytesBefore(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length,&nbsp;ByteBufIndexFinder&nbsp;indexFinder);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;copy();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;copy(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;slice();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;slice(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;duplicate();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasNioBuffer();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuffer&nbsp;nioBuffer();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuffer&nbsp;nioBuffer(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasNioBuffers();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuffer[]&nbsp;nioBuffers();<br />&nbsp;&nbsp;&nbsp;&nbsp;ByteBuffer[]&nbsp;nioBuffers(<span style="color: #0000FF; ">int</span>&nbsp;offset,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasArray();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">byte</span>[]&nbsp;array();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;arrayOffset();<br />&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;toString(Charset&nbsp;charset);<br />&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;toString(<span style="color: #0000FF; ">int</span>&nbsp;index,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;length,&nbsp;Charset&nbsp;charset);<br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;hashCode();<br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;equals(Object&nbsp;obj);<br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;compareTo(ByteBuf&nbsp;buffer);<br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;toString();<br />&nbsp;&nbsp;&nbsp;&nbsp;Unsafe&nbsp;unsafe();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">interface</span>&nbsp;Unsafe&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuffer&nbsp;nioBuffer();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuffer[]&nbsp;nioBuffers();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;newBuffer(<span style="color: #0000FF; ">int</span>&nbsp;initialCapacity);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;discardSomeReadBytes();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;acquire();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;release();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><p>&nbsp;</p>  <p align="left">&nbsp;</p>  <p align="center" style="text-align:center"><img src="http://www.blogjava.net/images/blogjava_net/czihong/ByteBuf_Index.JPG" border="0" alt="" width="483" height="103" /><br /></p>  <p align="center" style="text-align:center"><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ByteBuf Index</span></p>  <p align="center" style="text-align:center">&nbsp;</p>  <p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ByteBuf</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">通过两个指针来协助</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">I/O</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">的读写操作，读操作的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">readIndex</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">和写操作的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">writeIndex</span></p>  <p style="margin-top:0cm;margin-right:0cm;margin-bottom:8.05pt;margin-left: 0cm;line-height:10.75pt;background:white"><span style="font-size: 6.5pt;font-family:&quot;Courier New&quot;">readerIndex</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">和</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">writerIndex</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">都是一开始都是</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;">0</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">，随着数据的写入</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">writerIndex</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">会增加，读取数据会使</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;">readerIndex</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">增加，但是他不会超过</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">writerIndx</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">，在读取之后，</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;">0-readerIndex</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">的就被视为</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">discard</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">的</span><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;">.</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">调用</span><span style="font-size: 6.5pt;font-family:&quot;Courier New&quot;">discardReadBytes</span><span style="font-size: 6.5pt;Courier New&quot;;Courier New&quot;">方法</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">,</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">可以释放这部分空间</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;">,</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">他的作用类似</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ByeBuffer</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">的</span><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;">compact</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">方法</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">;</span></p>  <p style="margin: 0cm 0cm 8.05pt; line-height: 10.75pt; background-color: white; background-position: initial initial; background-repeat: initial initial;"><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;;background:yellow;">读和写的时候</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;background:yellow;">Index</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;; background:yellow;">是分开的，因此也就没必要再每次读完以后调用</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;background:yellow;">flip</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;; background:yellow;">方法，另外还有</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;background:yellow;">indexOf</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;;background: yellow;">、</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;background:yellow;">bytesBefore</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;;background:yellow;">等一些方便的方法；</span></p>  <p style="margin-top:0cm;margin-right:0cm;margin-bottom:8.05pt;margin-left: 0cm;line-height:10.75pt;background:white">&nbsp;</p>  <p style="margin-top:0cm;margin-right:0cm;margin-bottom:8.05pt;margin-left: 0cm;line-height:10.75pt;background:white"><span style="font-size: 6.5pt;font-family:&quot;Courier New&quot;">ByteBuf</span><span style="font-size:6.5pt;Courier New&quot;;Courier New&quot;">的几个重要方法</span></p>  <p><em><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;background:white">discardReadBytes()</span></em><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;"><br /> </span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;background:white">丢弃已读的内容。其执行过程如下：</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;"><br /> </span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;background:white">调用<span style="font-size: 6.5pt; font-family: 'Courier New'; background-position: initial initial; background-repeat: initial initial;">discardReadBytes()</span><span style="font-size: 6.5pt; background-position: initial initial; background-repeat: initial initial;">之前：</span></span></p>  <p align="center" style="text-align:center"><img src="http://www.blogjava.net/images/blogjava_net/czihong/Before_Discard_ByteBuf.JPG" border="0" alt="" width="480" height="99" /><br /></p>  <p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;; background:white">调用</span><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;background:white"> discardReadBytes()</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;background:white">方法后</span></p>  <p align="center" style="text-align:center"><img src="http://www.blogjava.net/images/blogjava_net/czihong/After_Discard_ByteBuf.JPG" border="0" alt="" width="499" height="100" /><br /></p>  <p><em><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;background:white">clear()</span></em><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;"><br /> </span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;background:white">丢弃所有的数据，并将<span style="font-size: 6.5pt; font-family: 'Courier New'; background-position: initial initial; background-repeat: initial initial;">readerIndex</span><span style="font-size: 6.5pt; background-position: initial initial; background-repeat: initial initial;">和</span><span style="font-size: 6.5pt; font-family: 'Courier New'; background-position: initial initial; background-repeat: initial initial;">writerIndex</span><span style="font-size: 6.5pt; background-position: initial initial; background-repeat: initial initial;">重置为</span><span style="font-size: 6.5pt; font-family: 'Courier New'; background-position: initial initial; background-repeat: initial initial;">0</span><span style="font-size: 6.5pt; background-position: initial initial; background-repeat: initial initial;">。</span></span></p>  <p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;"><br /> </span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;background:white">调用<span style="font-size: 6.5pt; font-family: 'Courier New'; background-position: initial initial; background-repeat: initial initial;">clear()</span><span style="font-size: 6.5pt; background-position: initial initial; background-repeat: initial initial;">之前</span></span></p>  <p align="center" style="text-align:center"><img src="http://www.blogjava.net/images/blogjava_net/czihong/Before_Clear_ByteBuf.JPG" border="0" alt="" width="480" height="100" /><br /></p>  <p align="left"><span style="font-size: 6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;background:white">调用</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;background:white">clear()</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;background:white">之后</span></p>  <p align="center" style="text-align:center"><img src="http://www.blogjava.net/images/blogjava_net/czihong/After_Clear_ByteBuf.JPG" border="0" alt="" width="480" height="103" /><br /></p>  <p align="center" style="text-align:center">&nbsp;</p>  <p align="left">&nbsp;<br />备注:因为笔者开始写Netty源码分析的时候，Netty 4.0还是处于Alpha阶段，之后的API可能还会有改动，笔者将会及时更改。使用开源已经有好几年的时间了，一直没有时间和精力来具体研究某个开源项目的具体实现，这次是第一次写开源项目的源码分析，如果文中有错误的地方，欢迎读者可以留言指出。对于转载的读者，请注明文章的出处。</p><div>希望和广大的开发者/开源爱好者进行交流，欢迎大家的留言和讨论。</div><img src ="http://www.blogjava.net/czihong/aggbug/391937.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-11-25 20:44 <a href="http://www.blogjava.net/czihong/articles/391937.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netty 4.0 源码分析（五）：ChannelHandlerContext和ChannelHandler</title><link>http://www.blogjava.net/czihong/articles/391932.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sun, 25 Nov 2012 08:51:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/391932.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/391932.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/391932.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/391932.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/391932.html</trackback:ping><description><![CDATA[<p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandlerContext</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">接口</span></p>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><span style="color: #008080; ">&nbsp;</span><span style="color: #008080;">1</span>&nbsp;<span style="color: #0000ff;">package</span>&nbsp;io.netty.channel;<br />
<span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;io.netty.buffer.ByteBuf;<br />
<span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;io.netty.buffer.MessageBuf;<br />
<span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;io.netty.util.AttributeMap;<br />
<span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;java.nio.channels.Channels;<br />
<span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;java.util.Set;<br />
<span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">interface</span>&nbsp;ChannelHandlerContext<br />
<span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;AttributeMap,&nbsp;ChannelFutureFactory,<br />
<span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ChannelInboundInvoker,&nbsp;ChannelOutboundInvoker&nbsp;{<br />
<span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Channel&nbsp;channel();<br />
<span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ChannelPipeline&nbsp;pipeline();<br />
<span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EventExecutor&nbsp;executor();<br />
<span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name();<br />
<span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ChannelHandler&nbsp;handler();<br />
<span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&lt;ChannelHandlerType&gt;&nbsp;types();<br />
<span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasInboundByteBuffer();<br />
<span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasInboundMessageBuffer();<br />
<span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;inboundByteBuffer();<br />
<span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;T&gt;&nbsp;MessageBuf&lt;T&gt;&nbsp;inboundMessageBuffer();<br />
<span style="color: #008080; ">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasOutboundByteBuffer();<br />
<span style="color: #008080; ">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasOutboundMessageBuffer();<br />
<span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;outboundByteBuffer();<br />
<span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;T&gt;&nbsp;MessageBuf&lt;T&gt;&nbsp;outboundMessageBuffer();<br />
<span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;replaceInboundByteBuffer(ByteBuf&nbsp;newInboundByteBuf);<br />
<span style="color: #008080; ">25</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;T&gt;&nbsp;MessageBuf&lt;T&gt;&nbsp;replaceInboundMessageBuffer(MessageBuf&lt;T&gt;&nbsp;newInboundMsgBuf);<br />
<span style="color: #008080; ">26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;replaceOutboundByteBuffer(ByteBuf&nbsp;newOutboundByteBuf);<br />
<span style="color: #008080; ">27</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;T&gt;&nbsp;MessageBuf&lt;T&gt;&nbsp;replaceOutboundMessageBuffer(MessageBuf&lt;T&gt;&nbsp;newOutboundMsgBuf);<br />
<span style="color: #008080; ">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasNextInboundByteBuffer();<br />
<span style="color: #008080; ">29</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasNextInboundMessageBuffer();<br />
<span style="color: #008080; ">30</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;nextInboundByteBuffer();<br />
<span style="color: #008080; ">31</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBuf&lt;Object&gt;&nbsp;nextInboundMessageBuffer();<br />
<span style="color: #008080; ">32</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasNextOutboundByteBuffer();<br />
<span style="color: #008080; ">33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;hasNextOutboundMessageBuffer();<br />
<span style="color: #008080; ">34</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;nextOutboundByteBuffer();<br />
<span style="color: #008080; ">35</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBuf&lt;Object&gt;&nbsp;nextOutboundMessageBuffer();<br />
<span style="color: #008080; ">36</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;isReadable();<br />
<span style="color: #008080; ">37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;readable(<span style="color: #0000FF; ">boolean</span>&nbsp;readable);<br />
<span style="color: #008080; ">38</span>&nbsp;}</div>
<p style="text-align: center; ">&nbsp;<img src="http://www.blogjava.net/images/blogjava_net/czihong/ChannelHandlerContext接口UML类.JPG" border="0" alt="" width="557" height="178" /></p>
<p> </p>
<p align="center" style="text-align:center"><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandlerContext</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">接口</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">UML</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">类</span></p>
<p align="center" style="text-align:center">&nbsp;</p>
<p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandlerContext</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">接口的几个重要方法</span></p>
<p align="left"><em><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">ChannelPipeline pipeline();</span></em></p>
<p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">返回属于当前</span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;;">ChannelHandlerContext</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;">ChannelPipeline</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;">。</span></p>
<p align="left">&nbsp;</p>
<p align="left"><span style="font-size:6.5pt;font-family: &quot;Courier New&quot;;">EventExecutor executor();</span></p>
<p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">EnventExcutor</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">用于调度</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">EventLoop</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">中的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">event</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">，这个方法返回当前的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">EventExecutor</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">。</span></p>
<p>&nbsp;</p>
<p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">一个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Handler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">可以有多个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Context</span></p>
<p><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">一个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">Handler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">可以被添加到多个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelPipeline</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">。这就意味着一个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">可以有多个</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandlerContext</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">接口</span></p>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">package</span>&nbsp;io.netty.channel;<br />
<span style="color: #008080; ">&nbsp;2</span>&nbsp;&nbsp;<br />
<span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;io.netty.channel.group.ChannelGroup;&nbsp;<br />
<span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;java.lang.annotation.Documented;<br />
<span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;java.lang.annotation.ElementType;<br />
<span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;java.lang.annotation.Inherited;<br />
<span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;java.lang.annotation.Retention;<br />
<span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;java.lang.annotation.RetentionPolicy;<br />
<span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;java.lang.annotation.Target;<br />
<span style="color: #008080; ">10</span>&nbsp;<span style="color: #0000FF; ">import</span>&nbsp;java.nio.channels.Channels;<br />
<span style="color: #008080; ">11</span>&nbsp;&nbsp;<br />
<span style="color: #008080; ">12</span>&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">interface</span>&nbsp;ChannelHandler&nbsp;{<br />
<span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;beforeAdd(ChannelHandlerContext&nbsp;ctx)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception;<br />
<span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;afterAdd(ChannelHandlerContext&nbsp;ctx)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception;<br />
<span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;beforeRemove(ChannelHandlerContext&nbsp;ctx)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception;<br />
<span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;afterRemove(ChannelHandlerContext&nbsp;ctx)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception;<br />
<span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;exceptionCaught(ChannelHandlerContext&nbsp;ctx,&nbsp;Throwable&nbsp;cause)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception;<br />
<span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;userEventTriggered(ChannelHandlerContext&nbsp;ctx,&nbsp;Object&nbsp;evt)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception;<br />
<span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Inherited<br />
<span style="color: #008080; ">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Documented<br />
<span style="color: #008080; ">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Target(ElementType.TYPE)<br />
<span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Retention(RetentionPolicy.RUNTIME)<br />
<span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@<span style="color: #0000FF; ">interface</span>&nbsp;Sharable&nbsp;{<br />
<span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;no&nbsp;value</span><span style="color: #008000; "><br />
</span><span style="color: #008080; ">25</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<span style="color: #008080; ">26</span>&nbsp;}</div>
<p><br />
</p>
<p style="text-align: center; ">&nbsp;<img src="http://www.blogjava.net/images/blogjava_net/czihong/ChannelHandler接口UML类.JPG" border="0" alt="" width="465" height="250" /></p>
<p> </p>
<p align="center" style="text-align:center"><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">类</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">UML</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">图</span></p>
<p align="left">&nbsp;</p>
<p align="left"><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">中的几个重要方法</span></p>
<p align="left"><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">有两个子接口，</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelUpstreamHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">和</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelDownstreamHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">。</span></p>
<p align="left" style="margin-left: 21pt; text-indent: -21pt;"><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;Courier New&quot;">1.<span style="font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;">ChannelUpstreamHandler</span><span style="font-size: 6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">用于处理和拦截</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">upstream</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">中的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelEvent</span></p>
<p align="left" style="margin-left: 21pt; text-indent: -21pt;"><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;;Courier New&quot;">2.<span style="font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp; </span></span><span style="font-size:6.5pt; font-family:&quot;Courier New&quot;">ChannelDownstreamHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">用于处理和拦截</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">downstream</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">中的</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelEvent</span></p>
<p align="left">&nbsp;</p>
<p align="left"><span style="font-size: 6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">状态信息</span></p>
<p align="left"><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;">ChannelHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;">一般需要存储一些状态信息，以下是【官方推荐】的方法，使用成员变量。</span></p>
<p align="left" style="background-color: white; background-position: initial initial; background-repeat: initial initial;"></p>
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;DataServerHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;SimpleChannelHandler&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">boolean</span>&nbsp;loggedIn;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;messageReceived(ChannelHandlerContext&nbsp;ctx,&nbsp;MessageEvent&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Channel&nbsp;ch&nbsp;=&nbsp;e.getChannel();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;o&nbsp;=&nbsp;e.getMessage();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(o&nbsp;<span style="color: #0000FF; ">instanceof</span>&nbsp;LoginMessage)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;authenticate((LoginMessage)&nbsp;o);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loggedIn&nbsp;=&nbsp;<span style="color: #0000FF; ">true</span>;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;(o&nbsp;<span style="color: #0000FF; ">instanceof</span>&nbsp;GetDataMessage)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(loggedIn)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch.write(fetchSecret((GetDataMessage)&nbsp;o));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fail();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /><br />
&nbsp;}<br />
&nbsp;<br />
<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Create&nbsp;a&nbsp;new&nbsp;handler&nbsp;instance&nbsp;per&nbsp;channel.<br />
&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;See&nbsp;ClientBootstrap#setPipelineFactory(ChannelPipelineFactory).</span><span style="color: #008000; "><br />
</span>&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;DataServerPipelineFactory&nbsp;<span style="color: #0000FF; ">implements</span>&nbsp;ChannelPipelineFactory&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;ChannelPipeline&nbsp;getPipeline()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;Channels.pipeline(<span style="color: #0000FF; ">new</span>&nbsp;DataServerHandler());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;}</div>
<p>&nbsp;</p>
<p align="left" style="background-color: white; background-position: initial initial; background-repeat: initial initial;">&nbsp;</p>
<p align="left" style="background-color: white; background-position: initial initial; background-repeat: initial initial;"><span style="font-size:6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;; color:#353833;">或者使用</span><span style="font-size:6.5pt;font-family:&quot;Courier New&quot;; color:#353833;">ChannelLocal</span><span style="font-size: 6.5pt;font-family:宋体;Courier New&quot;;Courier New&quot;;Courier New&quot;;color:#353833;">，代码如下</span></p>
<pre style="background:white"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;DataServerState&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;ChannelLocal&lt;Boolean&gt;&nbsp;loggedIn&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;ChannelLocal&lt;&gt;()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">protected</span>&nbsp;Boolean&nbsp;initialValue(Channel&nbsp;channel)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #0000FF; ">false</span>;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /><br />}<br />
&nbsp;@Sharable
&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;DataServerHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;SimpleChannelHandler&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;messageReceived(ChannelHandlerContext&nbsp;ctx,&nbsp;MessageEvent&nbsp;e)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Channel&nbsp;ch&nbsp;=&nbsp;e.getChannel();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;o&nbsp;=&nbsp;e.getMessage();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(o&nbsp;<span style="color: #0000FF; ">instanceof</span>&nbsp;LoginMessage)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;authenticate((LoginMessage)&nbsp;o);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataServerState.loggedIn.set(ch,&nbsp;<span style="color: #0000FF; ">true</span>);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;(o&nbsp;<span style="color: #0000FF; ">instanceof</span>&nbsp;GetDataMessage)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(DataServerState.loggedIn.get(ch))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctx.getChannel().write(fetchSecret((GetDataMessage)&nbsp;o));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fail();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /><br />}<br /><br />
&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Print&nbsp;the&nbsp;remote&nbsp;addresses&nbsp;of&nbsp;the&nbsp;authenticated&nbsp;clients:</span><span style="color: #008000; ">
</span>&nbsp;ChannelGroup&nbsp;allClientChannels&nbsp;=&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" />;
&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(Channel&nbsp;ch:&nbsp;allClientChannels)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(DataServerState.loggedIn.get(ch))&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(ch.getRemoteAddress());
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;}</div><div><br /><br />备注:因为笔者开始写Netty源码分析的时候，Netty 4.0还是处于Alpha阶段，之后的API可能还会有改动，笔者将会及时更改。使用开源已经有好几年的时间了，一直没有时间和精力来具体研究某个开源项目的具体实现，这次是第一次写开源项目的源码分析，如果文中有错误的地方，欢迎读者可以留言指出。对于转载的读者，请注明文章的出处。 希望和广大的开发者/开源爱好者进行交流，欢迎大家的留言和讨论。</div>
</pre><img src ="http://www.blogjava.net/czihong/aggbug/391932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-11-25 16:51 <a href="http://www.blogjava.net/czihong/articles/391932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netty 4.0 源码分析（三）：Channel和ChannelPipeline</title><link>http://www.blogjava.net/czihong/articles/391927.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sun, 25 Nov 2012 06:53:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/391927.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/391927.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/391927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/391927.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/391927.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Client和server通过Channel连接，然后通过ByteBuf进行传输。每个Channel有自己的Pipeline，Pipeline上面可以添加和定义Handler和Event。  &nbsp;  Channel类&nbsp;1&nbsp;package&nbsp;io.netty.channel;&nbsp;2&nbsp;import&nbsp;io.netty.buffer.Byte...&nbsp;&nbsp;<a href='http://www.blogjava.net/czihong/articles/391927.html'>阅读全文</a><img src ="http://www.blogjava.net/czihong/aggbug/391927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-11-25 14:53 <a href="http://www.blogjava.net/czihong/articles/391927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netty 4.0 源码分析（二）：Echo Server</title><link>http://www.blogjava.net/czihong/articles/391899.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sat, 24 Nov 2012 04:38:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/391899.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/391899.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/391899.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/391899.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/391899.html</trackback:ping><description><![CDATA[<p>Netty<span style="font-family:宋体;">项目中，自带了很多使用的例子，对于刚刚开始接触和学习</span>Netty<span style="font-family:宋体;">源码的开发者来说，可以通过例子来更好的理解</span>Netty<span style="font-family:宋体;">的具体实现。源码可以再netty 4.0的example找到。</span></p>  <p>&nbsp;<br /></p><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;EchoServerHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;ChannelInboundByteHandlerAdapter&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /><span style="color: #008080; ">&nbsp;2</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;Logger&nbsp;logger&nbsp;=&nbsp;Logger.getLogger(<br /><span style="color: #008080; ">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EchoServerHandler.<span style="color: #0000FF; ">class</span>.getName());<br /><span style="color: #008080; ">&nbsp;4</span>&nbsp;<br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;inboundBufferUpdated(ChannelHandlerContext&nbsp;ctx,&nbsp;ByteBuf&nbsp;in)&nbsp;{<br /><span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;out&nbsp;=&nbsp;ctx.nextOutboundByteBuffer();<br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.discardReadBytes();<br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.writeBytes(in);<br /><span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctx.flush();<br /><span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">12</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br /><span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;exceptionCaught(ChannelHandlerContext&nbsp;ctx,&nbsp;Throwable&nbsp;cause)&nbsp;{<br /><span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Close&nbsp;the&nbsp;connection&nbsp;when&nbsp;an&nbsp;exception&nbsp;is&nbsp;raised.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.log(Level.WARNING,&nbsp;"Unexpected&nbsp;exception&nbsp;from&nbsp;downstream.",&nbsp;cause);<br /><span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctx.close();<br /><span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">19</span>&nbsp;}</div>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-size: 9pt; font-family: 'Courier New';">Line 1:&nbsp;</span><span style="font-family:宋体;">声明一个</span>EchoServerHandler, <span style="font-family:宋体;">并且继承了</span><span style="font-size: 9pt; font-family: 'Courier New'; background-color: silver; background-position: initial initial; background-repeat: initial initial;">ChannelInboundByteHandlerAdapter</span><span style="font-size: 9pt; font-family: 宋体;">。</span> <span style="font-size: 9pt; font-family: 宋体;">这样</span><span style="font-size: 9pt; font-family: 'Courier New';">EchoServerHandler</span><span style="font-size: 9pt; font-family: 宋体;">就可以处理</span><span style="font-size: 9pt; font-family: 'Courier New';">client</span><span style="font-size: 9pt; font-family: 宋体;">发送过来的</span><span style="font-size: 9pt; font-family: 'Courier New';">request</span><span style="font-size: 9pt; font-family: 宋体;">。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-size: 9pt; font-family: 'Courier New';">Line 6:&nbsp;</span><span style="font-family:宋体;">重写</span>inboundBufferUpdated<span style="font-family:宋体;">方法，对</span>client<span style="font-family:宋体;">发送过来的</span>request<span style="font-family:宋体;">进行对</span>ByteBuffer<span style="font-family:宋体;">对象的操作。关于</span>ByteBuffer<span style="font-family:宋体;">的概念将在以后章节讨论。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-size: 9pt; font-family: 'Courier New';">Line 7: ctx.<span style="background:silver;">nextOutboundByteBuffer</span>()</span><span style="font-size: 9pt; font-family: 宋体;">将返回一个</span><span style="font-size: 9pt; font-family: 'Courier New';">ByteBuffer</span><span style="font-size: 9pt; font-family: 宋体;">对象。如果该对象不存在，那么抛出</span><span style="font-size: 9pt; font-family: 'Courier New';">UnsupportedOperationException</span><span style="font-size: 9pt; font-family: 宋体;">异常。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><font face="Courier New"><span style="font-size: 12px;">Line 14:&nbsp;</span></font><span style="font-family:宋体;">重写</span>exceptionCaught<span style="font-family:宋体;">在</span>server<span style="font-family:宋体;">端捕获异常。</span></p>  <p>&nbsp;</p>  <p align="left"></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;EchoServer&nbsp;{<br /><span style="color: #008080; ">&nbsp;2</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;port;<br /><span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;EchoServer(<span style="color: #0000FF; ">int</span>&nbsp;port)&nbsp;{<br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.port&nbsp;=&nbsp;port;<br /><span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;run()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br /><span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Configure&nbsp;the&nbsp;server.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServerBootstrap&nbsp;b&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;ServerBootstrap();<br /><span style="color: #008080; ">12</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>&nbsp;{<br /><span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.group(<span style="color: #0000FF; ">new</span>&nbsp;NioEventLoopGroup(),&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;NioEventLoopGroup())<br /><span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.channel(NioServerSocketChannel.<span style="color: #0000FF; ">class</span>)<br /><span style="color: #008080; ">15</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.option(ChannelOption.SO_BACKLOG,&nbsp;100)<br /><span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.localAddress(<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress(port))<br /><span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.childOption(ChannelOption.TCP_NODELAY,&nbsp;<span style="color: #0000FF; ">true</span>)<br /><span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.handler(<span style="color: #0000FF; ">new</span>&nbsp;LoggingHandler(LogLevel.INFO))<br /><span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.childHandler(<span style="color: #0000FF; ">new</span>&nbsp;ChannelInitializer&lt;SocketChannel&gt;()&nbsp;{<br /><span style="color: #008080; ">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br /><span style="color: #008080; ">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;initChannel(SocketChannel&nbsp;ch)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br /><span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch.pipeline().addLast(<br /><span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LoggingHandler(LogLevel.INFO),<br /><span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;EchoServerHandler());<br /><span style="color: #008080; ">25</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br /><span style="color: #008080; ">27</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Start&nbsp;the&nbsp;server.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">29</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ChannelFuture&nbsp;f&nbsp;=&nbsp;b.bind().sync();<br /><span style="color: #008080; ">30</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">31</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Wait&nbsp;until&nbsp;the&nbsp;server&nbsp;socket&nbsp;is&nbsp;closed.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">32</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.channel().closeFuture().sync();<br /><span style="color: #008080; ">33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">finally</span>&nbsp;{<br /><span style="color: #008080; ">34</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Shut&nbsp;down&nbsp;all&nbsp;event&nbsp;loops&nbsp;to&nbsp;terminate&nbsp;all&nbsp;threads.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">35</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.shutdown();<br /><span style="color: #008080; ">36</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">37</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">38</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">39</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br /><span style="color: #008080; ">40</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;port;<br /><span style="color: #008080; ">41</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(args.length&nbsp;&gt;&nbsp;0)&nbsp;{<br /><span style="color: #008080; ">42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port&nbsp;=&nbsp;Integer.parseInt(args[0]);<br /><span style="color: #008080; ">43</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br /><span style="color: #008080; ">44</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;port&nbsp;=&nbsp;8080;<br /><span style="color: #008080; ">45</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">46</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;EchoServer(port).run();<br /><span style="color: #008080; ">47</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">48</span>&nbsp;}</div><p>&nbsp;</p>  <p>&nbsp;</p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-size: 9pt;"><font face="Courier New">Line 11:&nbsp;</font></span><span style="font-size: 9pt; font-family: 宋体;">通过</span><span style="font-size: 9pt; font-family: 'Courier New';">ServerBootStrap</span><span style="font-size: 9pt; font-family: 宋体;">对象，来启动服务器</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">Line 13:&nbsp;<span style="font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;</span><span style="font-family:宋体;">通过</span>group<span style="font-family:宋体;">方法，来绑定</span>EventLoopGroup<span style="font-family:宋体;">，</span>EventLoopGroup<span style="font-family:宋体;">用来处理</span>SocketChannel<span style="font-family:宋体;">和</span>Channel<span style="font-family:宋体;">上面的所有时间和</span>IO<span style="font-family:宋体;">。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">Line 16: localAddress<span style="font-family:宋体;">方法用于绑定服务器地址和端口。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">Line 18,19: handler<span style="font-family:宋体;">方法和</span>childhandler<span style="font-family:宋体;">方法用于指定各种</span>ChannelHandler<span style="font-family:宋体;">对象，指定的</span>ChannelHandler<span style="font-family:宋体;">对象将用于处理</span>client<span style="font-family:宋体;">端来的</span>request<span style="font-family:宋体;">。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">Line 21:&nbsp;<span style="font-family:宋体;">初始化一个</span>Channel<span style="font-family:宋体;">对象，并且绑定之前定义的</span>EchoServerHandler<span style="font-family:宋体;">类。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">Line 22:&nbsp;<span style="font-size: 7pt; line-height: normal; font-family: 'Times New Roman';">&nbsp;</span><span style="font-family:宋体;">将</span>EchoServerHandler<span style="font-family:宋体;">添加到</span>Pipeline<span style="font-family:宋体;">中。</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">Line 29: ServerBootstrap<span style="font-family:宋体;">对象准备就绪，启动</span>server<span style="font-family:宋体;">，</span></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">Line 32:&nbsp;<span style="font-family:宋体;">等待直到</span>server socket<span style="font-family:宋体;">关闭</span></p>  <p>&nbsp;</p>  <p align="left"></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;EchoClientHandler&nbsp;<span style="color: #0000FF; ">extends</span>&nbsp;ChannelInboundByteHandlerAdapter&nbsp;{<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;Logger&nbsp;logger&nbsp;=&nbsp;Logger.getLogger(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EchoClientHandler.<span style="color: #0000FF; ">class</span>.getName());<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;ByteBuf&nbsp;firstMessage;<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/**</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Creates&nbsp;a&nbsp;client-side&nbsp;handler.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;EchoClientHandler(<span style="color: #0000FF; ">int</span>&nbsp;firstMessageSize)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(firstMessageSize&nbsp;&lt;=&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">throw</span>&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;IllegalArgumentException("firstMessageSize:&nbsp;"&nbsp;+&nbsp;firstMessageSize);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstMessage&nbsp;=&nbsp;Unpooled.buffer(firstMessageSize);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;(<span style="color: #0000FF; ">int</span>&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;firstMessage.capacity();&nbsp;i&nbsp;++)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstMessage.writeByte((<span style="color: #0000FF; ">byte</span>)&nbsp;i);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;channelActive(ChannelHandlerContext&nbsp;ctx)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctx.write(firstMessage);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;inboundBufferUpdated(ChannelHandlerContext&nbsp;ctx,&nbsp;ByteBuf&nbsp;in)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ByteBuf&nbsp;out&nbsp;=&nbsp;ctx.nextOutboundByteBuffer();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.discardReadBytes();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out.writeBytes(in);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctx.flush();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;exceptionCaught(ChannelHandlerContext&nbsp;ctx,&nbsp;Throwable&nbsp;cause)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Close&nbsp;the&nbsp;connection&nbsp;when&nbsp;an&nbsp;exception&nbsp;is&nbsp;raised.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.log(Level.WARNING,&nbsp;"Unexpected&nbsp;exception&nbsp;from&nbsp;downstream.",&nbsp;cause);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ctx.close();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><p>&nbsp;</p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;"><span style="font-size: 9pt; font-family: 'Courier New';">EchoClientHandler</span><span style="font-size: 9pt; font-family: 宋体;">类的实现与</span><span style="font-size: 9pt; font-family: 'Courier New';">EchoServerHandler</span><span style="font-size: 9pt; font-family: 宋体;">类似，也都继承了</span><span style="font-size: 9pt; font-family: 'Courier New'; background-color: silver; background-position: initial initial; background-repeat: initial initial;">ChannelInboundByteHandlerAdapter</span><span style="font-size: 9pt; font-family: 宋体;">。不同在于重写了</span><span style="font-size: 9pt; font-family: 'Courier New';">channelActive()</span><span style="font-size: 9pt; font-family: 宋体;">方法。</span></p>  <p>&nbsp;<br /></p><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;EchoClient&nbsp;{<br /><span style="color: #008080; ">&nbsp;2</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">&nbsp;3</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;String&nbsp;host;<br /><span style="color: #008080; ">&nbsp;4</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;port;<br /><span style="color: #008080; ">&nbsp;5</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;firstMessageSize;<br /><span style="color: #008080; ">&nbsp;6</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">&nbsp;7</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;EchoClient(String&nbsp;host,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;port,&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;firstMessageSize)&nbsp;{<br /><span style="color: #008080; ">&nbsp;8</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.host&nbsp;=&nbsp;host;<br /><span style="color: #008080; ">&nbsp;9</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.port&nbsp;=&nbsp;port;<br /><span style="color: #008080; ">10</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.firstMessageSize&nbsp;=&nbsp;firstMessageSize;<br /><span style="color: #008080; ">11</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">12</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">13</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;run()&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br /><span style="color: #008080; ">14</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Configure&nbsp;the&nbsp;client.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Bootstrap&nbsp;b&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Bootstrap();<br /><span style="color: #008080; ">16</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">try</span>&nbsp;{<br /><span style="color: #008080; ">17</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.group(<span style="color: #0000FF; ">new</span>&nbsp;NioEventLoopGroup())<br /><span style="color: #008080; ">18</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.channel(NioSocketChannel.<span style="color: #0000FF; ">class</span>)<br /><span style="color: #008080; ">19</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.option(ChannelOption.TCP_NODELAY,&nbsp;<span style="color: #0000FF; ">true</span>)<br /><span style="color: #008080; ">20</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.remoteAddress(<span style="color: #0000FF; ">new</span>&nbsp;InetSocketAddress(host,&nbsp;port))<br /><span style="color: #008080; ">21</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.handler(<span style="color: #0000FF; ">new</span>&nbsp;ChannelInitializer&lt;SocketChannel&gt;()&nbsp;{<br /><span style="color: #008080; ">22</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override<br /><span style="color: #008080; ">23</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;initChannel(SocketChannel&nbsp;ch)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br /><span style="color: #008080; ">24</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch.pipeline().addLast(<br /><span style="color: #008080; ">25</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;LoggingHandler(LogLevel.INFO),<br /><span style="color: #008080; ">26</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;EchoClientHandler(firstMessageSize));<br /><span style="color: #008080; ">27</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">28</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br /><span style="color: #008080; ">29</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">30</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Start&nbsp;the&nbsp;client.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">31</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ChannelFuture&nbsp;f&nbsp;=&nbsp;b.connect().sync();<br /><span style="color: #008080; ">32</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">33</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Wait&nbsp;until&nbsp;the&nbsp;connection&nbsp;is&nbsp;closed.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">34</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.channel().closeFuture().sync();<br /><span style="color: #008080; ">35</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">finally</span>&nbsp;{<br /><span style="color: #008080; ">36</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Shut&nbsp;down&nbsp;the&nbsp;event&nbsp;loop&nbsp;to&nbsp;terminate&nbsp;all&nbsp;threads.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">37</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.shutdown();<br /><span style="color: #008080; ">38</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">39</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">40</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">41</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)&nbsp;<span style="color: #0000FF; ">throws</span>&nbsp;Exception&nbsp;{<br /><span style="color: #008080; ">42</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Print&nbsp;usage&nbsp;if&nbsp;no&nbsp;argument&nbsp;is&nbsp;specified.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">43</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(args.length&nbsp;&lt;&nbsp;2&nbsp;||&nbsp;args.length&nbsp;&gt;&nbsp;3)&nbsp;{<br /><span style="color: #008080; ">44</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(<br /><span style="color: #008080; ">45</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"Usage:&nbsp;"&nbsp;+&nbsp;EchoClient.<span style="color: #0000FF; ">class</span>.getSimpleName()&nbsp;+<br /><span style="color: #008080; ">46</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&lt;host&gt;&nbsp;&lt;port&gt;&nbsp;[&lt;first&nbsp;message&nbsp;size&gt;]");<br /><span style="color: #008080; ">47</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br /><span style="color: #008080; ">48</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">49</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">50</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Parse&nbsp;options.</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">51</span>&nbsp;<span style="color: #008000; "></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;String&nbsp;host&nbsp;=&nbsp;args[0];<br /><span style="color: #008080; ">52</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;port&nbsp;=&nbsp;Integer.parseInt(args[1]);<br /><span style="color: #008080; ">53</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">final</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;firstMessageSize;<br /><span style="color: #008080; ">54</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(args.length&nbsp;==&nbsp;3)&nbsp;{<br /><span style="color: #008080; ">55</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstMessageSize&nbsp;=&nbsp;Integer.parseInt(args[2]);<br /><span style="color: #008080; ">56</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span style="color: #0000FF; ">else</span>&nbsp;{<br /><span style="color: #008080; ">57</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstMessageSize&nbsp;=&nbsp;256;<br /><span style="color: #008080; ">58</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">59</span>&nbsp;&nbsp;<br /><span style="color: #008080; ">60</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;EchoClient(host,&nbsp;port,&nbsp;firstMessageSize).run();<br /><span style="color: #008080; ">61</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><span style="color: #008080; ">62</span>&nbsp;}</div><p>&nbsp;</p>  <p><span style="font-size: 9pt;"><font face="Courier New">Line 20:&nbsp;</font></span><span style="font-size: 9pt; font-family: 宋体;">指定远程服务器的地址和端口（</span><span style="font-size: 9pt; font-family: 'Courier New';">localhost:8080</span><span style="font-size: 9pt; font-family: 宋体;">）<br /><br /><br /></span><div>备注:因为笔者开始写Netty源码分析的时候，Netty 4.0还是处于Alpha阶段，之后的API可能还会有改动，笔者将会及时更改。使用开源已经有好几年的时间了，一直没有时间和精力来具体研究某个开源项目的具体实现，这次是第一次写开源项目的源码分析，如果文中有错误的地方，欢迎读者可以留言指出。对于转载的读者，请注明文章的出处。</div><div>希望和广大的开发者/开源爱好者进行交流，欢迎大家的留言和讨论。</div></p><img src ="http://www.blogjava.net/czihong/aggbug/391899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-11-24 12:38 <a href="http://www.blogjava.net/czihong/articles/391899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netty 4.0 源码分析（一）：配置环境</title><link>http://www.blogjava.net/czihong/articles/391784.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Thu, 22 Nov 2012 13:21:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/391784.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/391784.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/391784.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/391784.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/391784.html</trackback:ping><description><![CDATA[<div>Netty 源码分析（一）：配置环境<br />1. 下载jdk + elipse + egit<br />2. 相关jar包下载<br />3. cynwin + telnet/ssh (setup.exe keywork:inetutils / ssh<strong style="padding: 0px; margin: 0px; color: #333333; font-family: Georgia, 'Times New Roman', serif; font-size: 12px; line-height: 18px; text-align: justify; background-color: #fafafa;">&nbsp;</strong>)<br />3. 从example包开始阅读<br /><br /><br /><div>备注:因为笔者开始写Netty源码分析的时候，Netty 4.0还是处于Alpha阶段，之后的API可能还会有改动，笔者将会及时更改。使用开源已经有好几年的时间了，一直没有时间和精力来具体研究某个开源项目的具体实现，这次是第一次写开源项目的源码分析，如果文中有错误的地方，欢迎读者可以留言指出。对于转载的读者，请注明文章的出处。</div><div>希望和广大的开发者/开源爱好者进行交流，欢迎大家的留言和讨论。</div></div><img src ="http://www.blogjava.net/czihong/aggbug/391784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-11-22 21:21 <a href="http://www.blogjava.net/czihong/articles/391784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>