ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>精品在线免费观看,中文字幕乱码久久午夜不卡 ,91精品久久久久久久91蜜桃http://www.aygfsteel.com/czihong/category/53023.htmlzh-cnThu, 24 Jan 2013 09:28:21 GMTThu, 24 Jan 2013 09:28:21 GMT60Netty 4.0 源码分析åQˆå…«åQ‰ï¼š(x¨¬)Netty 4.0中的io.netty.bufferåŒ?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/czihong/articles/392059.html</guid><wfw:comment>http://www.aygfsteel.com/czihong/comments/392059.html</wfw:comment><comments>http://www.aygfsteel.com/czihong/articles/392059.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/czihong/comments/commentRss/392059.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/czihong/services/trackbacks/392059.html</trackback:ping><description><![CDATA[     摘要: Netty 4.0的源码结构与之前çš?.X版本发生äº?ji¨£n)较大的变化åQŒä»¥ä¸‹æ˜¯Netty 4.0源码的层‹Æ¡ç»“æž? netty/    common/     - utility and logging    buffer/     - buffer API   ...  <a href='http://www.aygfsteel.com/czihong/articles/392059.html'>阅读全文</a><img src ="http://www.aygfsteel.com/czihong/aggbug/392059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/czihong/" target="_blank">Chan Chen</a> 2012-11-27 11:34 <a href="http://www.aygfsteel.com/czihong/articles/392059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netty 4.0 源码分析åQˆä¸ƒåQ‰ï¼š(x¨¬)AbstractBootstrap抽象¾c?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/czihong/articles/391953.html</guid><wfw:comment>http://www.aygfsteel.com/czihong/comments/391953.html</wfw:comment><comments>http://www.aygfsteel.com/czihong/articles/391953.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/czihong/comments/commentRss/391953.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/czihong/services/trackbacks/391953.html</trackback:ping><description><![CDATA[<p><span style="font-size:6.5pt;font-family:"Courier New"">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">是一个帮助类åQŒé€šè¿‡æ–ÒŽ(gu¨©)³•链(</span><span style="font-size:6.5pt;font-family:"Courier New"">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">åQ‰çš„æ–¹å¼åQŒæä¾›äº†(ji¨£n)一个简单易用的方式来配¾|?/span><span style="font-size:6.5pt;font-family:"Courier New"">Bootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">åQŒç„¶åŽå¯åЍ䏀ä¸?/span><span style="font-size:6.5pt;font-family:"Courier New"">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">。在理解</span><span style="font-size:6.5pt;font-family:"Courier New"">Netty</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">源码中的</span><span style="font-size:6.5pt;font-family:"Courier New"">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">åQ?/span><span style="font-size:6.5pt;font-family:"Courier New""> ServerBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">å’?/span><span style="font-size:6.5pt;font-family:"Courier New"">Bootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">之前åQŒåº”该先äº?ji¨£n)解一下什么是</span><span style="font-size:6.5pt;font-family:"Courier New"">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">ã€?br /></span></p> <p><span style="font-size:6.5pt;font-family:"Courier New""><br />Wiki</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">上面对于</span><span style="font-size:6.5pt;font-family:"Courier New"">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">的定义如下:(x¨¬)</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:"Courier New""><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";Courier New";Courier New"">在面向对象的¾~–程语言中,</span><span style="font-size:6.5pt;font-family:"Courier New"">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">是一¿Uç”¨äºŽè°ƒç”¨å¤šä¸ªæ–¹æ³•的常用技术。每个方法都ä¼?x¨¬)返回一个对象(可能是当前对象本íw«ï¼‰(j¨ª)åQŒè¿™æ ·åšçš„好处就是,通过一条语句,ž®±å¯ä»¥è®²æ‰€æœ‰çš„æ–ÒŽ(gu¨©)³•调用链接在一赗÷€?/span> </p> <p><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New""><br />定义有一些抽象,那么可以通过实际的例子来˜q›è¡Œç†è§£å’Œæ¶ˆåŒ–ã€?/span></p> <p><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">假设有一ä¸?/span><span style="font-size:6.5pt;font-family:"Courier New"">StringBuffer</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">的类åQŒç±»ä¸­æœ‰ä¸€ä¸?/span><span style="font-size:6.5pt;font-family:"Courier New"">append()</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">æ–ÒŽ(gu¨©)³•</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> <span style="color: #0000FF; ">class</span> StringBuffer {<br />  <span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">void</span> append(String str) {<br />    <span style="color: #008000; ">//</span><span style="color: #008000; "> <img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /> useful code <img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span style="color: #008000; "><br /></span>  }<br />}</div><p> </p> <p><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">˜q™ä¸ª¾cÀLœ‰¾~ºç‚¹ž®±æ˜¯è¯ß_(d¨¢)¼Œåœ¨å‘</span><span style="font-size:6.5pt;font-family:"Courier New"">StringBuffer</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">对象˜q½åŠ æ–°çš„å­—ç¬¦ä¸²çš„æ—¶å€™ï¼Œéœ€è¦åœ¨å¤šæ¡è¯­å¥ä¸­ï¼Œä¸æ–­çš„è°ƒç”?/span><span style="font-size:6.5pt;font-family:"Courier New"">append()</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">æ–ÒŽ(gu¨©)³•ã€?/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 sb = <span style="color: #0000FF; ">new</span> StringBuffer();<br />sb.append("Hello ");<br />sb.append(name);<br />sb.append("! Welcome!");</div></pre> <p><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">è€?/span><span style="font-size:6.5pt;font-family:"Courier New"">method chaining</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">的实玎ͼŒž®±å¯ä»¥é¿å…è¿™ä¸ªç¼ºé™—÷€?/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> <span style="color: #0000FF; ">class</span> StringBuffer {<br />  <span style="color: #0000FF; ">public</span> StringBuffer append(String str) {<br />    <span style="color: #008000; ">//</span><span style="color: #008000; "> <img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /> useful code <img src="http://www.aygfsteel.com/Images/dot.gif" alt="" /></span><span style="color: #008000; "><br /></span>    <span style="color: #0000FF; ">return</span> <span style="color: #0000FF; ">this</span>;<br />  }<br />}</div></pre> <p><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">现在我们ž®±å¯ä»¥å†ä¸€æ¡è¯­å¥ä¸­å®žçް½W¬ä¸€ä¸ªä¾‹å­çš„功能äº?ji¨£n)ã€?/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 sb = <span style="color: #0000FF; ">new</span> StringBuffer();<br />sb.append("Hello ").append(name).append("! Welcome!");</div></pre> <p><span style="font-size:6.5pt;font-family:"Courier New""><br />AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">抽象¾c?/span> <span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New"">åQˆéƒ¨åˆ†ä»£ç ï¼‰(j¨ª)</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> io.netty.bootstrap;<br /> <br /><span style="color: #0000FF; ">public</span> <span style="color: #0000FF; ">abstract</span> <span style="color: #0000FF; ">class</span> AbstractBootstrap<B <span style="color: #0000FF; ">extends</span> AbstractBootstrap<?>> {<br />    <span style="color: #0000FF; ">private</span> EventLoopGroup group;<br />    <span style="color: #0000FF; ">private</span> ChannelFactory factory;<br />    <span style="color: #0000FF; ">private</span> SocketAddress localAddress;<br />    <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">final</span> Map<ChannelOption<?>, Object> options = <span style="color: #0000FF; ">new</span> LinkedHashMap<ChannelOption<?>, Object>();<br />    <span style="color: #0000FF; ">private</span> <span style="color: #0000FF; ">final</span> Map<AttributeKey<?>, Object> attrs = <span style="color: #0000FF; ">new</span> LinkedHashMap<AttributeKey<?>, Object>();<br /><span style="color: #0000FF; ">private</span> ChannelHandler handler;<br /> <br />    @SuppressWarnings("unchecked")<br />    <span style="color: #0000FF; ">public</span> B group(EventLoopGroup group) {<br />        <span style="color: #0000FF; ">if</span> (group == <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> NullPointerException("group");<br />        }<br />        <span style="color: #0000FF; ">if</span> (<span style="color: #0000FF; ">this</span>.group != <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> IllegalStateException("group set already");<br />        }<br />        <span style="color: #0000FF; ">this</span>.group = group;<br />        <span style="color: #0000FF; ">return</span> (B) <span style="color: #0000FF; ">this</span>;<br />    }<br />    <span style="color: #0000FF; ">public</span> B channel(Class<? <span style="color: #0000FF; ">extends</span> Channel> channelClass) {<br />        <span style="color: #0000FF; ">if</span> (channelClass == <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> NullPointerException("channelClass");<br />        }<br />        <span style="color: #0000FF; ">return</span> channelFactory(<span style="color: #0000FF; ">new</span> BootstrapChannelFactory(channelClass));<br />    }<br />    @SuppressWarnings("unchecked")<br />    <span style="color: #0000FF; ">public</span> B channelFactory(ChannelFactory factory) {<br />        <span style="color: #0000FF; ">if</span> (factory == <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> NullPointerException("factory");<br />        }<br />        <span style="color: #0000FF; ">if</span> (<span style="color: #0000FF; ">this</span>.factory != <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> IllegalStateException("factory set already");<br />        }<br />        <span style="color: #0000FF; ">this</span>.factory = factory;<br />        <span style="color: #0000FF; ">return</span> (B) <span style="color: #0000FF; ">this</span>;<br />    }<br />    @SuppressWarnings("unchecked")<br />    <span style="color: #0000FF; ">public</span> B localAddress(SocketAddress localAddress) {<br />        <span style="color: #0000FF; ">this</span>.localAddress = localAddress;<br />        <span style="color: #0000FF; ">return</span> (B) <span style="color: #0000FF; ">this</span>;<br />    }<br />    @SuppressWarnings("unchecked")<br />    <span style="color: #0000FF; ">public</span> <T> B option(ChannelOption<T> option, T value) {<br />        <span style="color: #0000FF; ">if</span> (option == <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> NullPointerException("option");<br />        }<br />        <span style="color: #0000FF; ">if</span> (value == <span style="color: #0000FF; ">null</span>) {<br />            options.remove(option);<br />        } <span style="color: #0000FF; ">else</span> {<br />            options.put(option, value);<br />        }<br />        <span style="color: #0000FF; ">return</span> (B) <span style="color: #0000FF; ">this</span>;<br />    }<br />    <span style="color: #0000FF; ">public</span> <T> B attr(AttributeKey<T> key, T value) {<br />        <span style="color: #0000FF; ">if</span> (key == <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> NullPointerException("key");<br />        }<br />        <span style="color: #0000FF; ">if</span> (value == <span style="color: #0000FF; ">null</span>) {<br />            attrs.remove(key);<br />        } <span style="color: #0000FF; ">else</span> {<br />            attrs.put(key, value);<br />        }<br />        <span style="color: #0000FF; ">return</span> (B) <span style="color: #0000FF; ">this</span>;<br />    }<br />    @SuppressWarnings("unchecked")<br />    <span style="color: #0000FF; ">public</span> B handler(ChannelHandler handler) {<br />        <span style="color: #0000FF; ">if</span> (handler == <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> NullPointerException("handler");<br />        }<br />        <span style="color: #0000FF; ">this</span>.handler = handler;<br />        <span style="color: #0000FF; ">return</span> (B) <span style="color: #0000FF; ">this</span>;<br />    }<br />}</div><p> </p> <p align="left"> </p> <p align="left"><span style="font-size:6.5pt;font-family: "Courier New";">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">声明äº?ji¨£n)六个私有的成员变量åQ?/span><span style="font-size:6.5pt;font-family:"Courier New";">EventLoopGroup</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">对象åQ?/span><span style="font-size:6.5pt; font-family:"Courier New";">ChannelFacotry</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">对象åQ?/span><span style="font-size:6.5pt;font-family:"Courier New";">SockteAddress</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">对象åQ?/span><span style="font-size:6.5pt; font-family:"Courier New";">Map<ChannelOption<?>,Object></span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">对象åQ?/span><span style="font-size:6.5pt;font-family:"Courier New";">Map<Attribute<?>,Object></span><span style="font-size:6.5pt; font-family:宋体;Courier New";Courier New";Courier New";">对象åQ?/span><span style="font-size:6.5pt;font-family:"Courier New";">ChannelHandler</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">å¯¹è±¡ã€‚åÆˆä¸”æœ‰ç›¸å¯¹åº”çš„æ–ÒŽ(gu¨©)³•åQŒæ¥è®„¡½®˜q™äº›å¯¹è±¡åQŒå¦‚</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> B group(EventLoopGroup group) {<br />        <span style="color: #0000FF; ">if</span> (group == <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> NullPointerException("group");<br />        }<br />        <span style="color: #0000FF; ">if</span> (<span style="color: #0000FF; ">this</span>.group != <span style="color: #0000FF; ">null</span>) {<br />            <span style="color: #0000FF; ">throw</span> <span style="color: #0000FF; ">new</span> IllegalStateException("group set already");<br />        }<br />        <span style="color: #0000FF; ">this</span>.group = group;<br />        <span style="color: #0000FF; ">return</span> (B) <span style="color: #0000FF; ">this</span>;<br />}</div><p> </p> <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">通过传进来的</span><span style="font-size:6.5pt; font-family:"Courier New";">group</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">对象åQŒç„¶åŽå°†</span><span style="font-size:6.5pt;font-family:"Courier New";">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">中的</span><span style="font-size:6.5pt; font-family:"Courier New";">group</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">指向传进来的</span><span style="font-size:6.5pt;font-family:"Courier New";">group</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">。最¾lˆè¿”回的˜q˜æ˜¯</span><span style="font-size:6.5pt; font-family:"Courier New";">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">˜q™ä¸ªå½“前对象ã€?/span></p> <p align="left"> </p> <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">六个对象的作ç”?/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: "Courier New";">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";Courier New";Courier New";">用于处理ž®†è¦è¢«åˆ›å»ºçš„æ‰€æœ?/span><span style="font-size: 6.5pt;font-family:"Courier New";">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: "Courier New";">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";Courier New";Courier New";">建立一个工厂,用于以后çš?/span><span style="font-size: 6.5pt;font-family:"Courier New";">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">创徏</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: "Courier New";">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";Courier New";Courier New";">用于¾l‘定本地的网¾lœåœ°å€</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: "Courier New";">Map<ChannelOption<?>, Object> 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";Courier New";Courier New";">指定所创徏</span><span style="font-size:6.5pt; font-family:"Courier New";">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">的选项åQŒå¦‚</span><span style="font-size:6.5pt;font-family:"Courier New";">TCP_NODELAY</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">åQ?/span><span style="font-size:6.5pt; font-family:"Courier New";">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: "Courier New";">Map<AttributeKey<?>, Object> 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";Courier New";Courier New";">指定所创徏</span><span style="font-size:6.5pt; font-family:"Courier New";">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">的属æ€?/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: "Courier New";">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";Courier New";Courier New";">用于处理各类è¯äh±‚</span></p> </td> </tr> </tbody></table> <p align="left"> </p> <p align="left"><span style="font-size:6.5pt;font-family: "Courier New";">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">抽象¾cÈš„æŽ¥å£<br /></span></p><p> </p> <p align="center" style="text-align:center;text-autospace:none"><img src="http://www.aygfsteel.com/images/blogjava_net/czihong/AbstractBootstrap抽象¾c»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: "Courier New";">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">抽象¾c?/span><span style="font-size:6.5pt;font-family:"Courier New";">UML</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">å›?/span></p> <p align="left"> </p> <p align="left"><span style="font-size:6.5pt;font-family: "Courier New";">ServerBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">å’?/span><span style="font-size:6.5pt;font-family:"Courier New";">Bootstrap</span></p> <p align="left"><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">åœ?/span><span style="font-size:6.5pt; font-family:"Courier New";">Netty 4.0</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">中,</span><span style="font-size:6.5pt;font-family:"Courier New";">ServerBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">用于为服务器启动</span><span style="font-size:6.5pt; font-family:"Courier New";">ServerChannel</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">åQ?/span><span style="font-size:6.5pt;font-family:"Courier New";">Bootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">用于为客服端启动</span><span style="font-size:6.5pt; font-family:"Courier New";">Channel</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">。这两个¾cÀL˜¯</span><span style="font-size:6.5pt;font-family:"Courier New";">AbstractBootstrap</span><span style="font-size:6.5pt;font-family:宋体;Courier New";Courier New";Courier New";">的具体实现ã€?br /><br /></span></p><div>备注:因䨓(f¨´)½W”者开始写Netty源码分析的时候,Netty 4.0˜q˜æ˜¯å¤„于Alpha阶段åQŒä¹‹åŽçš„API可能˜q˜ä(sh¨´)¼š(x¨¬)有改动,½W”者将ä¼?x¨¬)å?qi¨¢ng)时更攏V€‚ä‹É用开源已¾læœ‰å¥½å‡ òq´çš„æ—‰™—´äº?ji¨£n),一直没有时间和¾_‘ÖŠ›æ¥å…·ä½“ç ”½I¶æŸä¸ªå¼€æºé¡¹ç›®çš„具体实现åQŒè¿™‹Æ¡æ˜¯½W¬ä¸€‹Æ¡å†™å¼€æºé¡¹ç›®çš„æºç åˆ†æžåQŒå¦‚果文中有错误的地方,‹Æ¢è¿Žè¯»è€…可以留­a€æŒ‡å‡ºã€‚对于è{载的读者,è¯äh³¨æ˜Žæ–‡ç« çš„出处ã€?/div><div>希望和广大的开发è€?开源爱好者进行交‹¹ï¼Œ‹Æ¢è¿Žå¤§å®¶çš„ç•™­a€å’Œè®¨è®ºã€?/div><p> </p><img src ="http://www.aygfsteel.com/czihong/aggbug/391953.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/czihong/" target="_blank">Chan Chen</a> 2012-11-26 10:57 <a href="http://www.aygfsteel.com/czihong/articles/391953.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Netty 4.0 源码分析åQˆå…­åQ‰ï¼š(x¨¬)EventLoopå’ŒEventLoopGrouphttp://www.aygfsteel.com/czihong/articles/391939.htmlChan ChenChan ChenSun, 25 Nov 2012 13:49:00 GMThttp://www.aygfsteel.com/czihong/articles/391939.htmlhttp://www.aygfsteel.com/czihong/comments/391939.htmlhttp://www.aygfsteel.com/czihong/articles/391939.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/391939.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/391939.htmlEventLoop相当于一ä¸?/span>Thread¾U¿ç¨‹åQŒè€?/span>EventLoopGroup则是½Ž¡ç†˜q™äº›EventLoopçš?/span>Thread¾U¿ç¨‹æ±?/span>

EventLoop接口

package io.netty.channel;

public interface EventLoop extends EventExecutor, EventLoopGroup {
    @Override
    EventLoopGroup parent();
}


EventLoop接口UML�/span>

parent()æ–ÒŽ(gu¨©)³•

˜q”回½Ž¡ç†˜q™ä¸ªEventLoopçš?/span>EventLoopGroupã€?/span>


EventLoopGroup接口

package io.netty.channel;
public interface EventLoopGroup extends EventExecutorGroup {
    @Override
    EventLoop next();
    ChannelFuture register(Channel channel);
    ChannelFuture register(Channel channel, ChannelFuture future);
}


EventLoopGroup接口UML�/span>

 

next()

˜q”回下一ä¸?/span>EventLoop

register(Channel channel)

指定一�/span>EventLoopGroup来注册某�/span>Channel�br />

备注:因䨓(f¨´)½W”者开始写Netty源码分析的时候,Netty 4.0˜q˜æ˜¯å¤„于Alpha阶段åQŒä¹‹åŽçš„API可能˜q˜ä(sh¨´)¼š(x¨¬)有改动,½W”者将ä¼?x¨¬)å?qi¨¢ng)时更攏V€‚ä‹É用开源已¾læœ‰å¥½å‡ òq´çš„æ—‰™—´äº?ji¨£n),一直没有时间和¾_‘ÖŠ›æ¥å…·ä½“ç ”½I¶æŸä¸ªå¼€æºé¡¹ç›®çš„具体实现åQŒè¿™‹Æ¡æ˜¯½W¬ä¸€‹Æ¡å†™å¼€æºé¡¹ç›®çš„æºç åˆ†æžåQŒå¦‚果文中有错误的地方,‹Æ¢è¿Žè¯»è€…可以留­a€æŒ‡å‡ºã€‚对于è{载的读者,è¯äh³¨æ˜Žæ–‡ç« çš„出处ã€?/div>
希望和广大的开发è€?开源爱好者进行交‹¹ï¼Œ‹Æ¢è¿Žå¤§å®¶çš„ç•™­a€å’Œè®¨è®ºã€?/div>



]]>Netty 4.0 源码分析åQˆå››åQ‰ï¼š(x¨¬)ByteBufhttp://www.aygfsteel.com/czihong/articles/391937.htmlChan ChenChan ChenSun, 25 Nov 2012 12:44:00 GMThttp://www.aygfsteel.com/czihong/articles/391937.htmlhttp://www.aygfsteel.com/czihong/comments/391937.htmlhttp://www.aygfsteel.com/czihong/articles/391937.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/391937.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/391937.htmlNetty是基于流的消息传递机制ã€?/span>Netty框架中,所有消息的传输都依赖于ByteBuf接口åQ?/span>ByteBufæ˜?/span>Netty NIO框架中的¾~“冲区ã€?/span>ByteBuf接口可以理解ä¸ÞZ¸€èˆ¬çš„Byte数组åQŒä¸˜q?/span>Nettyå¯?/span>Byte˜q›è¡Œäº?ji¨£n)封装,增加了(ji¨£n)一些实用的æ–ÒŽ(gu¨©)³•ã€?/span>


ChannelBuf接口

package io.netty.buffer;
public interface ChannelBuf {
    ChannelBufType type();
    boolean isPooled();
}


ByteBuf接口 

package io.netty.buffer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
public interface ByteBuf extends ChannelBuf, Comparable<ByteBuf> {
    int capacity();
    ByteBuf capacity(int newCapacity);
    int maxCapacity();
    ByteOrder order();
    ByteBuf order(ByteOrder endianness);
    boolean isDirect();
    int readerIndex();
    ByteBuf readerIndex(int readerIndex);
    int writerIndex();
    ByteBuf writerIndex(int writerIndex);
    ByteBuf setIndex(int readerIndex, int writerIndex);
    int readableBytes();
    int writableBytes();
    boolean readable();
    boolean writable();
    ByteBuf clear();
    ByteBuf markReaderIndex();
    ByteBuf resetReaderIndex();
    ByteBuf markWriterIndex();
    ByteBuf resetWriterIndex();
    ByteBuf discardReadBytes();
    ByteBuf ensureWritableBytes(int minWritableBytes);
    int ensureWritableBytes(int minWritableBytes, boolean force);
    boolean getBoolean(int index);
    byte  getByte(int index);
    short getUnsignedByte(int index);
    short getShort(int index);
    int getUnsignedShort(int index);
    int   getMedium(int index);
    int   getUnsignedMedium(int index);
    int   getInt(int index);
    long  getUnsignedInt(int index);
    long  getLong(int index);
    char  getChar(int index);
    float getFloat(int index);
    double getDouble(int index);
    ByteBuf getBytes(int index, ByteBuf dst);
    ByteBuf getBytes(int index, ByteBuf dst, int length);
    ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length);
    ByteBuf getBytes(int index, byte[] dst);
    ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length);
    ByteBuf getBytes(int index, ByteBuffer dst);
    ByteBuf getBytes(int index, OutputStream out, int length) throws IOException;
    int getBytes(int index, GatheringByteChannel out, int length) throws IOException;
    ByteBuf setBoolean(int index, boolean value);
    ByteBuf setByte(int index, int value);
    ByteBuf setShort(int index, int value);
    ByteBuf setMedium(int index, int   value);
    ByteBuf setInt(int index, int   value);
    ByteBuf setLong(int index, long  value);
    ByteBuf setChar(int index, int value);
    ByteBuf setFloat(int index, float value);
    ByteBuf setDouble(int index, double value);
    ByteBuf setBytes(int index, ByteBuf src);
    ByteBuf setBytes(int index, ByteBuf src, int length);
    ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length);
    ByteBuf setBytes(int index, byte[] src);
    ByteBuf setBytes(int index, byte[] src, int srcIndex, int length);
    ByteBuf setBytes(int index, ByteBuffer src);
    int setBytes(int index, InputStream in, int length) throws IOException;
    int  setBytes(int index, ScatteringByteChannel in, int length) throws IOException;
    ByteBuf setZero(int index, int length);
     boolean readBoolean();
    byte  readByte();
    short readUnsignedByte();
    short readShort();
    int   readUnsignedShort();
    int   readMedium();
    int   readUnsignedMedium();
    int   readInt();
    long  readUnsignedInt();
    long  readLong();
    char  readChar();
    float readFloat();
    double readDouble();
    ByteBuf readBytes(int length);
    ByteBuf readSlice(int length);
    ByteBuf readBytes(ByteBuf dst);
    ByteBuf readBytes(ByteBuf dst, int length);
    ByteBuf readBytes(ByteBuf dst, int dstIndex, int length);
    ByteBuf readBytes(byte[] dst);
    ByteBuf readBytes(byte[] dst, int dstIndex, int length);
    ByteBuf readBytes(ByteBuffer dst);
    ByteBuf readBytes(OutputStream out, int length) throws IOException;
    int  readBytes(GatheringByteChannel out, int length) throws IOException;
    ByteBuf skipBytes(int length);
    ByteBuf writeBoolean(boolean value);
    ByteBuf writeByte(int value);
    ByteBuf writeShort(int value);
    ByteBuf writeMedium(int   value);
    ByteBuf writeInt(int   value);
    ByteBuf writeLong(long  value);
    ByteBuf writeChar(int value);
    ByteBuf writeFloat(float value);
    ByteBuf writeDouble(double value);
    ByteBuf writeBytes(ByteBuf src);
    ByteBuf writeBytes(ByteBuf src, int length);
    ByteBuf writeBytes(ByteBuf src, int srcIndex, int length);
    ByteBuf writeBytes(byte[] src);
    ByteBuf writeBytes(byte[] src, int srcIndex, int length);
    ByteBuf writeBytes(ByteBuffer src);
    int  writeBytes(InputStream in, int length) throws IOException;
    int  writeBytes(ScatteringByteChannel in, int length) throws IOException;
    ByteBuf writeZero(int length);
    int indexOf(int fromIndex, int toIndex, byte value);
    int indexOf(int fromIndex, int toIndex, ByteBufIndexFinder indexFinder);
    int bytesBefore(byte value);
    int bytesBefore(ByteBufIndexFinder indexFinder);
    int bytesBefore(int length, byte value);
    int bytesBefore(int length, ByteBufIndexFinder indexFinder);
    int bytesBefore(int index, int length, byte value);
    int bytesBefore(int index, int length, ByteBufIndexFinder indexFinder);
    ByteBuf copy();
    ByteBuf copy(int index, int length);
    ByteBuf slice();
    ByteBuf slice(int index, int length);
    ByteBuf duplicate();
    boolean hasNioBuffer();
    ByteBuffer nioBuffer();
    ByteBuffer nioBuffer(int index, int length);
    boolean hasNioBuffers();
    ByteBuffer[] nioBuffers();
    ByteBuffer[] nioBuffers(int offset, int length);
    boolean hasArray();
    byte[] array();
    int arrayOffset();
    String toString(Charset charset);
    String toString(int index, int length, Charset charset);
    @Override
    int hashCode();
    @Override
    boolean equals(Object obj);
    @Override
    int compareTo(ByteBuf buffer);
    @Override
    String toString();
    Unsafe unsafe();
    interface Unsafe {
        ByteBuffer nioBuffer();
        ByteBuffer[] nioBuffers();
        ByteBuf newBuffer(int initialCapacity);
        void discardSomeReadBytes();
        void acquire();
        void release();
    }
}

 

 


ByteBuf Index

 

ByteBuf通过两个指针来协åŠ?/span>I/O的读写操作,è¯ÀL“ä½œçš„readIndex和写操作çš?/span>writeIndex

readerIndexå’?/span>writerIndex都是一开始都æ˜?/span>0åQŒéšç€æ•°æ®çš„写å…?/span>writerIndexä¼?x¨¬)增加,è¯Õd–数据ä¼?x¨¬)ä‹?/span>readerIndex增加åQŒä½†æ˜¯ä»–不会(x¨¬)­‘…过writerIndxåQŒåœ¨è¯Õd–之后åQ?/span>0-readerIndex的就被视ä¸?/span>discardçš?/span>.调用discardReadBytesæ–ÒŽ(gu¨©)³•,可以释放˜q™éƒ¨åˆ†ç©ºé—?/span>,他的作用¾cÖM¼¼ByeBufferçš?/span>compactæ–ÒŽ(gu¨©)³•;

è¯Õd’Œå†™çš„æ—¶å€?/span>Index是分开的,因此也就没必要再每次è¯Õd®Œä»¥åŽè°ƒç”¨flipæ–ÒŽ(gu¨©)³•åQŒå¦å¤–还æœ?/span>indexOfã€?/span>bytesBefore½{‰ä¸€äº›æ–¹ä¾¿çš„æ–ÒŽ(gu¨©)³•åQ?/span>

 

ByteBuf的几个重要方�/span>

discardReadBytes()
丢弃已读的内宏V€‚其执行˜q‡ç¨‹å¦‚下åQ?/span>
调用discardReadBytes()之前åQ?/span>


调用 discardReadBytes()æ–ÒŽ(gu¨©)³•å?/span>


clear()
丢弃所有的数据åQŒåƈž®?span style="font-size: 6.5pt; font-family: 'Courier New'; background-position: initial initial; background-repeat: initial initial;">readerIndexå’?/span>writerIndex重置ä¸?/span>0ã€?/span>


调用clear()之前


调用clear()之后


 

 
备注:因䨓(f¨´)½W”者开始写Netty源码分析的时候,Netty 4.0˜q˜æ˜¯å¤„于Alpha阶段åQŒä¹‹åŽçš„API可能˜q˜ä(sh¨´)¼š(x¨¬)有改动,½W”者将ä¼?x¨¬)å?qi¨¢ng)时更攏V€‚ä‹É用开源已¾læœ‰å¥½å‡ òq´çš„æ—‰™—´äº?ji¨£n),一直没有时间和¾_‘ÖŠ›æ¥å…·ä½“ç ”½I¶æŸä¸ªå¼€æºé¡¹ç›®çš„具体实现åQŒè¿™‹Æ¡æ˜¯½W¬ä¸€‹Æ¡å†™å¼€æºé¡¹ç›®çš„æºç åˆ†æžåQŒå¦‚果文中有错误的地方,‹Æ¢è¿Žè¯»è€…可以留­a€æŒ‡å‡ºã€‚对于è{载的读者,è¯äh³¨æ˜Žæ–‡ç« çš„出处ã€?/p>

希望和广大的开发è€?开源爱好者进行交‹¹ï¼Œ‹Æ¢è¿Žå¤§å®¶çš„ç•™­a€å’Œè®¨è®ºã€?/div>

]]>Netty 4.0 源码分析åQˆäº”åQ‰ï¼š(x¨¬)ChannelHandlerContextå’ŒChannelHandlerhttp://www.aygfsteel.com/czihong/articles/391932.htmlChan ChenChan ChenSun, 25 Nov 2012 08:51:00 GMThttp://www.aygfsteel.com/czihong/articles/391932.htmlhttp://www.aygfsteel.com/czihong/comments/391932.htmlhttp://www.aygfsteel.com/czihong/articles/391932.html#Feedback3http://www.aygfsteel.com/czihong/comments/commentRss/391932.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/391932.htmlChannelHandlerContext接口

 1 package io.netty.channel;
 2 import io.netty.buffer.ByteBuf;
 3 import io.netty.buffer.MessageBuf;
 4 import io.netty.util.AttributeMap;
 5 import java.nio.channels.Channels;
 6 import java.util.Set;
 7 public interface ChannelHandlerContext
 8          extends AttributeMap, ChannelFutureFactory,
 9                  ChannelInboundInvoker, ChannelOutboundInvoker {
10     Channel channel();
11     ChannelPipeline pipeline();
12     EventExecutor executor();
13     String name();
14     ChannelHandler handler();
15     Set<ChannelHandlerType> types();
16     boolean hasInboundByteBuffer();
17     boolean hasInboundMessageBuffer();
18     ByteBuf inboundByteBuffer();
19     <T> MessageBuf<T> inboundMessageBuffer();
20     boolean hasOutboundByteBuffer();
21     boolean hasOutboundMessageBuffer();
22     ByteBuf outboundByteBuffer();
23     <T> MessageBuf<T> outboundMessageBuffer();
24     ByteBuf replaceInboundByteBuffer(ByteBuf newInboundByteBuf);
25     <T> MessageBuf<T> replaceInboundMessageBuffer(MessageBuf<T> newInboundMsgBuf);
26     ByteBuf replaceOutboundByteBuffer(ByteBuf newOutboundByteBuf);
27     <T> MessageBuf<T> replaceOutboundMessageBuffer(MessageBuf<T> newOutboundMsgBuf);
28     boolean hasNextInboundByteBuffer();
29     boolean hasNextInboundMessageBuffer();
30     ByteBuf nextInboundByteBuffer();
31     MessageBuf<Object> nextInboundMessageBuffer();
32     boolean hasNextOutboundByteBuffer();
33     boolean hasNextOutboundMessageBuffer();
34     ByteBuf nextOutboundByteBuffer();
35     MessageBuf<Object> nextOutboundMessageBuffer();
36     boolean isReadable();
37     void readable(boolean readable);
38 }

 

ChannelHandlerContext接口UML¾c?/span>

 

ChannelHandlerContext接口的几个重要方�/span>

ChannelPipeline pipeline();

˜q”回属于当前ChannelHandlerContextçš?/span>ChannelPipelineã€?/span>

 

EventExecutor executor();

EnventExcutor用于调度EventLoop中的eventåQŒè¿™ä¸ªæ–¹æ³•返回当前的EventExecutorã€?/span>

 

一�/span>Handler可以有多�/span>Context

一ä¸?/span>Handler可以被添加到多个ChannelPipeline。这ž®±æ„å‘³ç€ä¸€ä¸?/span>ChannelHandler可以有多ä¸?/span>ChannelHandlerContextã€?/span>

 

 

ChannelHandler接口

 1 package io.netty.channel;
 2  
 3 import io.netty.channel.group.ChannelGroup; 
 4 import java.lang.annotation.Documented;
 5 import java.lang.annotation.ElementType;
 6 import java.lang.annotation.Inherited;
 7 import java.lang.annotation.Retention;
 8 import java.lang.annotation.RetentionPolicy;
 9 import java.lang.annotation.Target;
10 import java.nio.channels.Channels;
11  
12 public interface ChannelHandler {
13     void beforeAdd(ChannelHandlerContext ctx) throws Exception;
14     void afterAdd(ChannelHandlerContext ctx) throws Exception;
15     void beforeRemove(ChannelHandlerContext ctx) throws Exception;
16     void afterRemove(ChannelHandlerContext ctx) throws Exception;
17     void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception;
18     void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception;
19     @Inherited
20     @Documented
21     @Target(ElementType.TYPE)
22     @Retention(RetentionPolicy.RUNTIME)
23     @interface Sharable {
24         // no value
25     }
26 }


 

ChannelHandler¾c?/span>UMLå›?/span>

 

ChannelHandler中的几个重要æ–ÒŽ(gu¨©)³•

ChannelHandler有两个子接口åQ?/span>ChannelUpstreamHandlerå’?/span>ChannelDownstreamHandlerã€?/span>

1.    ChannelUpstreamHandler用于处理和拦æˆ?/span>upstream中的ChannelEvent

2.    ChannelDownstreamHandler用于处理和拦æˆ?/span>downstream中的ChannelEvent

 

状态信�/span>

ChannelHandler一般需要存储一些状态信息,以下是【官æ–ÒŽ(gu¨©)Ž¨èã€‘çš„æ–ÒŽ(gu¨©)³•åQŒä‹É用成员变量ã€?/span>

public class DataServerHandler extends SimpleChannelHandler {
     private boolean loggedIn;
     @Override
     public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
         Channel ch = e.getChannel();
         Object o = e.getMessage();
         if (o instanceof LoginMessage) {
             authenticate((LoginMessage) o);
             loggedIn = true;
         } else (o instanceof GetDataMessage) {
             if (loggedIn) {
                 ch.write(fetchSecret((GetDataMessage) o));
             } else {
                 fail();
             }
         }
     }
     
 }
 
// Create a new handler instance per channel.
 
// See ClientBootstrap#setPipelineFactory(ChannelPipelineFactory).
 public class DataServerPipelineFactory implements ChannelPipelineFactory {
     public ChannelPipeline getPipeline() {
         return Channels.pipeline(new DataServerHandler());
     }
 }

 

 

或者ä‹Éç”?/span>ChannelLocalåQŒä»£ç å¦‚ä¸?/span>

public final class DataServerState {      public static final ChannelLocal<Boolean> loggedIn = new ChannelLocal<>() {          protected Boolean initialValue(Channel channel) {              return false;          }      }      
}
 @Sharable  public class DataServerHandler extends SimpleChannelHandler {      @Override      public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {          Channel ch = e.getChannel();          Object o = e.getMessage();          if (o instanceof LoginMessage) {              authenticate((LoginMessage) o);              DataServerState.loggedIn.set(ch, true);          } else (o instanceof GetDataMessage) {              if (DataServerState.loggedIn.get(ch)) {                  ctx.getChannel().write(fetchSecret((GetDataMessage) o));              } else {                  fail();              }          }      }      
}

 // Print the remote addresses of the authenticated clients:  ChannelGroup allClientChannels = ;  for (Channel ch: allClientChannels) {      if (DataServerState.loggedIn.get(ch)) {          System.out.println(ch.getRemoteAddress());      }  }


备注:因䨓(f¨´)½W”者开始写Netty源码分析的时候,Netty 4.0˜q˜æ˜¯å¤„于Alpha阶段åQŒä¹‹åŽçš„API可能˜q˜ä(sh¨´)¼š(x¨¬)有改动,½W”者将ä¼?x¨¬)å?qi¨¢ng)时更攏V€‚ä‹É用开源已¾læœ‰å¥½å‡ òq´çš„æ—‰™—´äº?ji¨£n),一直没有时间和¾_‘ÖŠ›æ¥å…·ä½“ç ”½I¶æŸä¸ªå¼€æºé¡¹ç›®çš„具体实现åQŒè¿™‹Æ¡æ˜¯½W¬ä¸€‹Æ¡å†™å¼€æºé¡¹ç›®çš„æºç åˆ†æžåQŒå¦‚果文中有错误的地方,‹Æ¢è¿Žè¯»è€…可以留­a€æŒ‡å‡ºã€‚对于è{载的读者,è¯äh³¨æ˜Žæ–‡ç« çš„出处ã€?希望和广大的开发è€?开源爱好者进行交‹¹ï¼Œ‹Æ¢è¿Žå¤§å®¶çš„ç•™­a€å’Œè®¨è®ºã€?/div>


]]>
Netty 4.0 源码分析åQˆä¸‰åQ‰ï¼š(x¨¬)Channelå’ŒChannelPipelinehttp://www.aygfsteel.com/czihong/articles/391927.htmlChan ChenChan ChenSun, 25 Nov 2012 06:53:00 GMThttp://www.aygfsteel.com/czihong/articles/391927.htmlhttp://www.aygfsteel.com/czihong/comments/391927.htmlhttp://www.aygfsteel.com/czihong/articles/391927.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/391927.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/391927.html阅读全文

]]>
Netty 4.0 源码分析åQˆäºŒåQ‰ï¼š(x¨¬)Echo Serverhttp://www.aygfsteel.com/czihong/articles/391899.htmlChan ChenChan ChenSat, 24 Nov 2012 04:38:00 GMThttp://www.aygfsteel.com/czihong/articles/391899.htmlhttp://www.aygfsteel.com/czihong/comments/391899.htmlhttp://www.aygfsteel.com/czihong/articles/391899.html#Feedback1http://www.aygfsteel.com/czihong/comments/commentRss/391899.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/391899.htmlNetty™å¹ç›®ä¸­ï¼Œè‡ªå¸¦äº?ji¨£n)很多ä‹É用的例子åQŒå¯¹äºŽåˆšåˆšå¼€å§‹æŽ¥è§¦å’Œå­¦ä¹ (f¨¤n)Netty源码的开发者来è¯ß_(d¨¢)¼Œå¯ä»¥é€šè¿‡ä¾‹å­æ¥æ›´å¥½çš„理解Netty的具体实现。源码可以再netty 4.0çš„example扑ֈ°ã€?/span>

 

 1 public class EchoServerHandler extends ChannelInboundByteHandlerAdapter {            
 2     private static final Logger logger = Logger.getLogger(
 3             EchoServerHandler.class.getName());
 4 
 5     @Override
 6     public void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf in) {
 7         ByteBuf out = ctx.nextOutboundByteBuffer();
 8         out.discardReadBytes();
 9         out.writeBytes(in);
10         ctx.flush();
11     }
12  
13     @Override
14     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
15         // Close the connection when an exception is raised.
16         logger.log(Level.WARNING, "Unexpected exception from downstream.", cause);
17         ctx.close();
18     }
19 }

Line 1: å£°æ˜Žä¸€ä¸?/span>EchoServerHandler, òq¶ä¸”¾l§æ‰¿äº?/span>ChannelInboundByteHandlerAdapterã€?/span> ˜q™æ ·EchoServerHandlerž®±å¯ä»¥å¤„ç?/span>client发送过来的requestã€?/span>

Line 6: é‡å†™inboundBufferUpdatedæ–ÒŽ(gu¨©)³•åQŒå¯¹client发送过来的request˜q›è¡Œå¯?/span>ByteBuffer对象的操作。关äº?/span>ByteBuffer的概念将在以后章节讨论ã€?/span>

Line 7: ctx.nextOutboundByteBuffer()ž®†è¿”回一ä¸?/span>ByteBuffer对象。如果该对象不存在,那么抛出UnsupportedOperationException异常ã€?/span>

Line 14: é‡å†™exceptionCaughtåœ?/span>server端捕获异常ã€?/span>

 

 1 public class EchoServer {
 2  
 3     private final int port;
 4  
 5     public EchoServer(int port) {
 6         this.port = port;
 7     }
 8  
 9     public void run() throws Exception {
10         // Configure the server.
11         ServerBootstrap b = new ServerBootstrap();
12         try {
13             b.group(new NioEventLoopGroup(), new NioEventLoopGroup())
14              .channel(NioServerSocketChannel.class)
15              .option(ChannelOption.SO_BACKLOG, 100)
16              .localAddress(new InetSocketAddress(port))
17              .childOption(ChannelOption.TCP_NODELAY, true)
18              .handler(new LoggingHandler(LogLevel.INFO))
19              .childHandler(new ChannelInitializer<SocketChannel>() {
20                  @Override
21                  public void initChannel(SocketChannel ch) throws Exception {
22                      ch.pipeline().addLast(
23                              new LoggingHandler(LogLevel.INFO),
24                              new EchoServerHandler());
25                  }
26              });
27  
28             // Start the server.
29             ChannelFuture f = b.bind().sync();
30  
31             // Wait until the server socket is closed.
32             f.channel().closeFuture().sync();
33         } finally {
34             // Shut down all event loops to terminate all threads.
35             b.shutdown();
36         }
37     }
38  
39     public static void main(String[] args) throws Exception {
40         int port;
41         if (args.length > 0) {
42             port = Integer.parseInt(args[0]);
43         } else {
44             port = 8080;
45         }
46         new EchoServer(port).run();
47     }
48 }

 

 

Line 11: é€šè¿‡ServerBootStrap对象åQŒæ¥å¯åŠ¨æœåŠ¡å™?/span>

Line 13:  é€šè¿‡groupæ–ÒŽ(gu¨©)³•åQŒæ¥¾l‘定EventLoopGroupåQ?/span>EventLoopGroup用来处理SocketChannelå’?/span>Channel上面的所有时间和IOã€?/span>

Line 16: localAddressæ–ÒŽ(gu¨©)³•用于¾l‘定服务器地址和端口ã€?/span>

Line 18,19: handleræ–ÒŽ(gu¨©)³•å’?/span>childhandleræ–ÒŽ(gu¨©)³•用于指定各种ChannelHandler对象åQŒæŒ‡å®šçš„ChannelHandler对象ž®†ç”¨äºŽå¤„ç?/span>client端来çš?/span>requestã€?/span>

Line 21: åˆå§‹åŒ–一ä¸?/span>Channel对象åQŒåƈ且绑定之前定义的EchoServerHandler¾c…R€?/span>

Line 22:  ž®?/span>EchoServerHandleræ·ÕdŠ åˆ?/span>Pipeline中ã€?/span>

Line 29: ServerBootstrap对象准备ž®ÞqÈAåQŒå¯åŠ?/span>serveråQ?/span>

Line 32: ½{‰å¾…直到server socket关闭

 

public class EchoClientHandler extends ChannelInboundByteHandlerAdapter {
 
    private static final Logger logger = Logger.getLogger(
            EchoClientHandler.class.getName());
 
    private final ByteBuf firstMessage;
 
    /**
     * Creates a client-side handler.
     
*/
    public EchoClientHandler(int firstMessageSize) {
        if (firstMessageSize <= 0) {
            throw new IllegalArgumentException("firstMessageSize: " + firstMessageSize);
        }
        firstMessage = Unpooled.buffer(firstMessageSize);
        for (int i = 0; i < firstMessage.capacity(); i ++) {
            firstMessage.writeByte((byte) i);
        }
    }
 
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.write(firstMessage);
    }
 
    @Override
    public void inboundBufferUpdated(ChannelHandlerContext ctx, ByteBuf in) {
        ByteBuf out = ctx.nextOutboundByteBuffer();
        out.discardReadBytes();
        out.writeBytes(in);
        ctx.flush();
    }
 
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        logger.log(Level.WARNING, "Unexpected exception from downstream.", cause);
        ctx.close();
    }
}

 

EchoClientHandler¾cȝš„实现ä¸?/span>EchoServerHandler¾cÖM¼¼åQŒä¹Ÿéƒ½ç‘ô承了(ji¨£n)ChannelInboundByteHandlerAdapter。不同在于重写了(ji¨£n)channelActive()æ–ÒŽ(gu¨©)³•ã€?/span>

 

 1 public class EchoClient {
 2  
 3     private final String host;
 4     private final int port;
 5     private final int firstMessageSize;
 6  
 7     public EchoClient(String host, int port, int firstMessageSize) {
 8         this.host = host;
 9         this.port = port;
10         this.firstMessageSize = firstMessageSize;
11     }
12  
13     public void run() throws Exception {
14         // Configure the client.
15         Bootstrap b = new Bootstrap();
16         try {
17             b.group(new NioEventLoopGroup())
18              .channel(NioSocketChannel.class)
19              .option(ChannelOption.TCP_NODELAY, true)
20              .remoteAddress(new InetSocketAddress(host, port))
21              .handler(new ChannelInitializer<SocketChannel>() {
22                  @Override
23                  public void initChannel(SocketChannel ch) throws Exception {
24                      ch.pipeline().addLast(
25                              new LoggingHandler(LogLevel.INFO),
26                              new EchoClientHandler(firstMessageSize));
27                  }
28              });
29  
30             // Start the client.
31             ChannelFuture f = b.connect().sync();
32  
33             // Wait until the connection is closed.
34             f.channel().closeFuture().sync();
35         } finally {
36             // Shut down the event loop to terminate all threads.
37             b.shutdown();
38         }
39     }
40  
41     public static void main(String[] args) throws Exception {
42         // Print usage if no argument is specified.
43         if (args.length < 2 || args.length > 3) {
44             System.err.println(
45                     "Usage: " + EchoClient.class.getSimpleName() +
46                     " <host> <port> [<first message size>]");
47             return;
48         }
49  
50         // Parse options.
51         final String host = args[0];
52         final int port = Integer.parseInt(args[1]);
53         final int firstMessageSize;
54         if (args.length == 3) {
55             firstMessageSize = Integer.parseInt(args[2]);
56         } else {
57             firstMessageSize = 256;
58         }
59  
60         new EchoClient(host, port, firstMessageSize).run();
61     }
62 }

 

Line 20: æŒ‡å®š˜qœç¨‹æœåŠ¡å™¨çš„åœ°å€å’Œç«¯å£ï¼ˆlocalhost:8080åQ?br />

备注:因䨓(f¨´)½W”者开始写Netty源码分析的时候,Netty 4.0˜q˜æ˜¯å¤„于Alpha阶段åQŒä¹‹åŽçš„API可能˜q˜ä(sh¨´)¼š(x¨¬)有改动,½W”者将ä¼?x¨¬)å?qi¨¢ng)时更攏V€‚ä‹É用开源已¾læœ‰å¥½å‡ òq´çš„æ—‰™—´äº?ji¨£n),一直没有时间和¾_‘ÖŠ›æ¥å…·ä½“ç ”½I¶æŸä¸ªå¼€æºé¡¹ç›®çš„具体实现åQŒè¿™‹Æ¡æ˜¯½W¬ä¸€‹Æ¡å†™å¼€æºé¡¹ç›®çš„æºç åˆ†æžåQŒå¦‚果文中有错误的地方,‹Æ¢è¿Žè¯»è€…可以留­a€æŒ‡å‡ºã€‚对于è{载的读者,è¯äh³¨æ˜Žæ–‡ç« çš„出处ã€?/div>
希望和广大的开发è€?开源爱好者进行交‹¹ï¼Œ‹Æ¢è¿Žå¤§å®¶çš„ç•™­a€å’Œè®¨è®ºã€?/div>



]]>Netty 4.0 源码分析åQˆä¸€åQ‰ï¼š(x¨¬)配置环境http://www.aygfsteel.com/czihong/articles/391784.htmlChan ChenChan ChenThu, 22 Nov 2012 13:21:00 GMThttp://www.aygfsteel.com/czihong/articles/391784.htmlhttp://www.aygfsteel.com/czihong/comments/391784.htmlhttp://www.aygfsteel.com/czihong/articles/391784.html#Feedback0http://www.aygfsteel.com/czihong/comments/commentRss/391784.htmlhttp://www.aygfsteel.com/czihong/services/trackbacks/391784.htmlNetty 源码分析åQˆä¸€åQ‰ï¼š(x¨¬)配置环境
1. 下蝲jdk + elipse + egit
2. 相关jar包下è½?br />3. cynwin + telnet/ssh (setup.exe keywork:inetutils / ssh )
3. 从example包开始阅�br />

备注:因䨓(f¨´)½W”者开始写Netty源码分析的时候,Netty 4.0˜q˜æ˜¯å¤„于Alpha阶段åQŒä¹‹åŽçš„API可能˜q˜ä(sh¨´)¼š(x¨¬)有改动,½W”者将ä¼?x¨¬)å?qi¨¢ng)时更攏V€‚ä‹É用开源已¾læœ‰å¥½å‡ òq´çš„æ—‰™—´äº?ji¨£n),一直没有时间和¾_‘ÖŠ›æ¥å…·ä½“ç ”½I¶æŸä¸ªå¼€æºé¡¹ç›®çš„具体实现åQŒè¿™‹Æ¡æ˜¯½W¬ä¸€‹Æ¡å†™å¼€æºé¡¹ç›®çš„æºç åˆ†æžåQŒå¦‚果文中有错误的地方,‹Æ¢è¿Žè¯»è€…可以留­a€æŒ‡å‡ºã€‚对于è{载的读者,è¯äh³¨æ˜Žæ–‡ç« çš„出处ã€?/div>
希望和广大的开发è€?开源爱好者进行交‹¹ï¼Œ‹Æ¢è¿Žå¤§å®¶çš„ç•™­a€å’Œè®¨è®ºã€?/div>


]]> Ö÷Õ¾Ö©Öë³ØÄ£°å£º Ô˳ÇÊÐ| ÓàÒ¦ÊÐ| Í©Â®ÏØ| »ªÍ¤ÏØ| ¾²ÄþÏØ| À´°²ÏØ| ÜdzÇÏØ| äàÑôÊÐ| ³¤¸ðÊÐ| ¿Æ¼¼| °²ÐÂÏØ| ÒË´ºÊÐ| ¾®¸ÔɽÊÐ| Ì«°×ÏØ| ÕÑͨÊÐ| ¶«·½ÊÐ| ¶«°²ÏØ| ¶÷ƽÊÐ| äÀ´¨ÏØ| ÓÀÌ©ÏØ| ºªµ¦ÊÐ| ÖÙ°ÍÏØ| ÏÌÄþÊÐ| Î¢É½ÏØ| ¸ßÑôÏØ| ϲµÂÏØ| ÁÉÑôÊÐ| êùÎªÏØ| Í©ÏçÊÐ| ÕÑÆ½ÏØ| Òí³ÇÏØ| Àû½òÏØ| á°¸ÞÏØ| ÍÁÄ¬ÌØÓÒÆì| ºÍÁÖ¸ñ¶ûÏØ| ÁÖÖÝÊÐ| ½­´¨ÏØ| ¶«ÎÚ| ¾üÊÂ| Û·ÉÆÏØ| ÕÑËÕÏØ|