ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品在线观看免费,美女国产一区二区,国内精品视频久久http://www.aygfsteel.com/alex-zheng/category/47156.html---on my wayzh-cnThu, 31 Mar 2011 01:36:58 GMTThu, 31 Mar 2011 01:36:58 GMT60正则表达å¼åŒ¹é…多个字½W¦ä¸²ä¸­ä¸€ä¸ªæˆ–多个http://www.aygfsteel.com/alex-zheng/articles/347257.htmlalex_zhengalex_zhengWed, 30 Mar 2011 02:22:00 GMThttp://www.aygfsteel.com/alex-zheng/articles/347257.htmlhttp://www.aygfsteel.com/alex-zheng/comments/347257.htmlhttp://www.aygfsteel.com/alex-zheng/articles/347257.html#Feedback0http://www.aygfsteel.com/alex-zheng/comments/commentRss/347257.htmlhttp://www.aygfsteel.com/alex-zheng/services/trackbacks/347257.html ^(((width|height)\s*:\s*\d+(px|%)[;]?)|\s|(float:(left|right)[;]?))+$
˜q™é‡Œæ²¡æœ‰å¯šw‡å¤å®šä¹‰åšå¤„ç†

alex_zheng 2011-03-30 10:22 å‘表评论
]]>
巧用ä½è¿½Ž—表½Cºå±žæ€§åˆ†¾c?/title><link>http://www.aygfsteel.com/alex-zheng/articles/344806.html</link><dc:creator>alex_zheng</dc:creator><author>alex_zheng</author><pubDate>Tue, 22 Feb 2011 03:07:00 GMT</pubDate><guid>http://www.aygfsteel.com/alex-zheng/articles/344806.html</guid><wfw:comment>http://www.aygfsteel.com/alex-zheng/comments/344806.html</wfw:comment><comments>http://www.aygfsteel.com/alex-zheng/articles/344806.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/alex-zheng/comments/commentRss/344806.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/alex-zheng/services/trackbacks/344806.html</trackback:ping><description><![CDATA[有时候,我们希望用一个字ŒDµä¿å­˜å¯¹è±¡çš„æ‰€å±žçŠ¶æ€æˆ–分类åQŒå½“˜q™ä¸ªå€¼å­˜åœ¨å¤š¿U组åˆçš„æ—¶å€™ï¼Œæˆ‘们ž®±å¯ä»¥ä‹É用佘qç®—æ¥è¡¨½Cºç»„åˆåŽçš„倹{€?br /> 先定义类型A=1,B=2,C=4,D=8,E=16½{?çš„å€æ•°,<br /> 那么objectAå›_±žäºŽAåˆå±žäºŽC,å…¶å€égØ“A|C,æ·ÕdŠ ¾cÕdž‹ä½¿ç”¨|åQˆæˆ–åQ‰è¿½Ž—,¿U»é™¤¾cÕdž‹ä½¿ç”¨^(异或)˜qç®—åQŒåˆ¤æ–­æ˜¯å¦å±žäºŽæŸä¸ªç±»åž‹ä‹Éç”?amp;˜qç®—ã€?br /> A=00000001<br /> B=00000010<br /> C=00000100<br /> D=00001000<br /> E=00010000<br /> <br /> objectA = (A|B|C = 00000111)<br /> 去除B¾cÕdž‹ 00000111<br />               ^00000010<br /> -------------------------<br />                  00000101=(A|C)<br /> <br /> åˆ¤æ–­æ˜¯å¦æ˜¯A,00000101&00000001 = 00000001<br /> <br /> <br /> <br /> <img src ="http://www.aygfsteel.com/alex-zheng/aggbug/344806.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/alex-zheng/" target="_blank">alex_zheng</a> 2011-02-22 11:07 <a href="http://www.aygfsteel.com/alex-zheng/articles/344806.html#Feedback" target="_blank" style="text-decoration:none;">å‘表评论</a></div>]]></description></item><item><title>eclipse中xml的自动æ½Cºé…¾|?è½?http://www.aygfsteel.com/alex-zheng/articles/343078.htmlalex_zhengalex_zhengMon, 17 Jan 2011 01:31:00 GMThttp://www.aygfsteel.com/alex-zheng/articles/343078.htmlhttp://www.aygfsteel.com/alex-zheng/comments/343078.htmlhttp://www.aygfsteel.com/alex-zheng/articles/343078.html#Feedback0http://www.aygfsteel.com/alex-zheng/comments/commentRss/343078.htmlhttp://www.aygfsteel.com/alex-zheng/services/trackbacks/343078.htmlhttp://hi.baidu.com/2wiki/blog/item/2cc40a3f2b7ef2c97c1e7127.html
DTD ¾cÕdž‹¾U¦æŸæ–‡äšg
    1. Window->Preferences->XML->XML Catalog->User Specified Entries½H—å£ä¸?选择Add 按纽
       
    2.在Add XML Catalog Entry å¯¹è¯æ¡†ä¸­é€‰æ‹©æˆ–输入以下内å®?
        Location: F:\soft\programmingSoft\Framework\Ibatis\sql-map-config-2.dtd
        Key Type: URI
        KEY: http://ibatis.apache.org/dtd/sql-map-config-2.dtd
       
XSD ¾cÕdž‹¾U¦æŸæ–‡äšg

    1. Window->Preferences->XML->XML Catalog->User Specified Entries½H—å£ä¸?选择Add 按纽
       
    2.在Add XML Catalog Entry å¯¹è¯æ¡†ä¸­é€‰æ‹©æˆ–输入以下内å®?
        Location: F:\soft\programmingSoft\Framework\Spring\spring-framework-2.5.6.SEC01-with-dependencies\spring-framework-2.5.6.SEC01\dist\resources\spring-beans-2.5.xsd
        Key Type: Schema Location
        KEY: http://www.springframework.org/schema/beans/spring-beans-2.5.xsd



alex_zheng 2011-01-17 09:31 å‘表评论
]]>
hibernateæºç org.hibernate.hql.antlråŒ…äØ“½Iºçš„解决æ–ÒŽ³•http://www.aygfsteel.com/alex-zheng/articles/340639.htmlalex_zhengalex_zhengTue, 14 Dec 2010 06:23:00 GMThttp://www.aygfsteel.com/alex-zheng/articles/340639.htmlhttp://www.aygfsteel.com/alex-zheng/comments/340639.htmlhttp://www.aygfsteel.com/alex-zheng/articles/340639.html#Feedback0http://www.aygfsteel.com/alex-zheng/comments/commentRss/340639.htmlhttp://www.aygfsteel.com/alex-zheng/services/trackbacks/340639.html 首先ž®†antlr.jar包å¤åˆ¶åˆ°hibernate-distribution-3.5.6-Final/project/core/src/main/antlr,˜q™é‡Œhibernate-distribution-3.5.6-Final是你的解压èµ\å¾?br /> ç„¶åŽä¾æ¬¡æ‰§è¡Œjava -classpath antlr-2.7.6.jar antlr.Tool hql.g½{‰ï¼Œæœ€åŽå°†ç”Ÿæˆçš„javaæ–‡äšgå¤åˆ¶åˆ°ç›¸åº”包



alex_zheng 2010-12-14 14:23 å‘表评论
]]>
nettyæºç åˆ†æžž®ç»“http://www.aygfsteel.com/alex-zheng/articles/340157.htmlalex_zhengalex_zhengThu, 09 Dec 2010 08:46:00 GMThttp://www.aygfsteel.com/alex-zheng/articles/340157.htmlhttp://www.aygfsteel.com/alex-zheng/comments/340157.htmlhttp://www.aygfsteel.com/alex-zheng/articles/340157.html#Feedback0http://www.aygfsteel.com/alex-zheng/comments/commentRss/340157.htmlhttp://www.aygfsteel.com/alex-zheng/services/trackbacks/340157.html channelfutureè´Ÿè´£channel的所处状æ€ï¼Œä¸€ä¸ªchannleä¸­å…³è”æ¥channelpipelineåQŒchannelpipeline则由pipelinefactory创å¾åQ?br /> 在channelpipeline中有内部¾c»channelhandlercontextåQŒä¿å­˜channelhandler的链å¼ç»“构,由channelhandleræ¥ä¼ é€’channeleventåQ?br /> channelevent分别有openåQŒbindåQŒconnectedåQŒcloseåQŒmessagereceived½{‰ã€?br />


alex_zheng 2010-12-09 16:46 å‘表评论
]]>
netty3.2.3æºç åˆ†æž-ClientBootstrapå¯åŠ¨åˆ†æžhttp://www.aygfsteel.com/alex-zheng/articles/339908.htmlalex_zhengalex_zhengMon, 06 Dec 2010 08:59:00 GMThttp://www.aygfsteel.com/alex-zheng/articles/339908.htmlhttp://www.aygfsteel.com/alex-zheng/comments/339908.htmlhttp://www.aygfsteel.com/alex-zheng/articles/339908.html#Feedback0http://www.aygfsteel.com/alex-zheng/comments/commentRss/339908.htmlhttp://www.aygfsteel.com/alex-zheng/services/trackbacks/339908.html
public class TelnetClient {

    
public static void main(String[] args) throws Exception {
        
        ClientBootstrap bootstrap 
= new ClientBootstrap(
                
new NioClientSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool()));

        
// Configure the pipeline factory.
        bootstrap.setPipelineFactory(new TelnetClientPipelineFactory());

        
// Start the connection attempt.
        ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));

        
// Wait until the connection attempt succeeds or fails.
        Channel channel = future.awaitUninterruptibly().getChannel();
        
if (!future.isSuccess()) {
            future.getCause().printStackTrace();
            bootstrap.releaseExternalResources();
            
return;
        }

        
    }
}
直接看connectæ–ÒŽ³•
public ChannelFuture connect(final SocketAddress remoteAddress, final SocketAddress localAddress) {

        
if (remoteAddress == null) {
            
throw new NullPointerException("remoteAddress");
        }

        ChannelPipeline pipeline;
        
try {
            pipeline 
= getPipelineFactory().getPipeline();
        } 
catch (Exception e) {
            
throw new ChannelPipelineException("Failed to initialize a pipeline.", e);
        }

        
// Set the options.
        
//NioClientSocketChannel构造函æ•îC¸­ä¼šè§¦å‘channelopen
        
//TelnetClientPipelineFactory中的upstreamhandler没有é‡å†™channelOpenåQŒè¿™é‡Œåªæ˜¯ä¸€ç›´å¾€ä¸‹ä¼ é€’该事äšg
        Channel ch = getFactory().newChannel(pipeline);
        ch.getConfig().setOptions(getOptions());

        
// Bind.
        if (localAddress != null) {
            ch.bind(localAddress);
        }

        
// Connect.
        return ch.connect(remoteAddress);
    }
ç„¶åŽæ‰§è¡Œch.connect(remoteAddress);
˜q™é‡Œæ˜¯NioClientSocketChannel-->NioSocketChannel-->AbstractChannel
public ChannelFuture connect(SocketAddress remoteAddress) {
       
return Channels.connect(this, remoteAddress);
}

public static ChannelFuture connect(Channel channel, SocketAddress remoteAddress) {
        
if (remoteAddress == null) {
            
throw new NullPointerException("remoteAddress");
        }
        ChannelFuture future 
= future(channel, true);
        channel.getPipeline().sendDownstream(
new DownstreamChannelStateEvent(
                channel, future, ChannelState.CONNECTED, remoteAddress));
        
return future;
}

从TelnetClientPipelineFactoryçš„pipeline中由下往上传递CONNECTED事äšgåQŒè¿™é‡Œåªæœ‰ä¸€ä¸ªStringEncoder-->OneToOneEncoder,å…?br /> handleDownstreamæ–ÒŽ³•对该事äšgä¸åšå¤„ç†,往上传递该事äšg,执行DefaultChannelHandlerContext.sendDownstream
public void sendDownstream(ChannelEvent e) {
            
//在StringEncoder之å‰å†æ²¡æœ‰downstreamhandler
            DefaultChannelHandlerContext prev = getActualDownstreamContext(this.prev);
            
if (prev == null) {
                
try {
                    getSink().eventSunk(DefaultChannelPipeline.
this, e);
                } 
catch (Throwable t) {
                    notifyHandlerException(e, t);
                }
            } 
else {
                DefaultChannelPipeline.
this.sendDownstream(prev, e);
            }
        }
执行NioClientSocketPipelineSink.eventSunk,其中会执�br />
 private void connect(
            
final NioClientSocketChannel channel, final ChannelFuture cf,
            SocketAddress remoteAddress) {
        
try {
            
//如果˜q”回trueåQŒè°ƒç”¨nioworker.register,开始å¯åЍnioworker¾U¿ç¨‹å¤„ç†è¯¥channel的读å†?br />             //å¦åˆ™åQŒäº¤¾l™boss.registeræ–ÒŽ³•åQŒåœ¨boss¾U¿ç¨‹ä¸­å®Œæˆè¿žæŽ?/span>
            if (channel.socket.connect(remoteAddress)) {
                channel.worker.register(channel, cf);
            } 
else {
                
//为当å‰clientsocketchannelæ·ÕdŠ closedçš„listener
                channel.getCloseFuture().addListener(new ChannelFutureListener() {
                    
public void operationComplete(ChannelFuture f)
                            
throws Exception {
                        
if (!cf.isDone()) {
                            cf.setFailure(
new ClosedChannelException());
                        }
                    }
                });
                cf.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
                channel.connectFuture 
= cf;
                
                boss.register(channel);
            }

        } 
catch (Throwable t) {
            cf.setFailure(t);
            fireExceptionCaught(channel, t);
            channel.worker.close(channel, succeededFuture(channel));
        }
    }

执行boss.registeråQŒåœ¨boss¾U¿ç¨‹ä¸­ç¡®ä¿è¯¥channel˜qžæŽ¥æˆåŠŸåQŒè¿™é‡Œä¼šå¯åЍboss¾U¿ç¨‹
void register(NioClientSocketChannel channel) {
            
//在RegisterTaskçš„runæ–ÒŽ³•里注册SelectionKey.OP_CONNECT
            Runnable registerTask = new RegisterTask(this, channel);
            
                
boolean offered = registerTaskQueue.offer(registerTask);
                
assert offered;
            }

            
if (wakenUp.compareAndSet(falsetrue)) {
                selector.wakeup();
            }
        }
最åŽå¯åЍboss.runåQŒå…¶ä¸­processSelectedKeys里执行connect
private void connect(SelectionKey k) {
            NioClientSocketChannel ch 
= (NioClientSocketChannel) k.attachment();
            
try {
                
if (ch.socket.finishConnect()) {
                    k.cancel();
                    
//˜qžæŽ¥æˆåŠŸåQŒæ‰åœ¨nioworker中å¯åŠ¨ä¸€ä¸ªæ–°¾U¿ç¨‹æ¥å¤„ç†è¯¥socketchannel的读å†?/span>
                    ch.worker.register(ch, ch.connectFuture);
                }
            } 
catch (Throwable t) {
                ch.connectFuture.setFailure(t);
                fireExceptionCaught(ch, t);
                ch.worker.close(ch, succeededFuture(ch));
            }
        }

之厞®±æ˜¯äº¤ç»™nioworker¾U¿ç¨‹æ¥è¿›è¡Œæ•°æ®çš„å‘é€å’ŒæŽ¥æ”¶äº†ã€?br />

alex_zheng 2010-12-06 16:59 å‘表评论
]]>
java-string¾cÕdž‹å‚数传递分æž?/title><link>http://www.aygfsteel.com/alex-zheng/articles/339846.html</link><dc:creator>alex_zheng</dc:creator><author>alex_zheng</author><pubDate>Sun, 05 Dec 2010 08:27:00 GMT</pubDate><guid>http://www.aygfsteel.com/alex-zheng/articles/339846.html</guid><wfw:comment>http://www.aygfsteel.com/alex-zheng/comments/339846.html</wfw:comment><comments>http://www.aygfsteel.com/alex-zheng/articles/339846.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/alex-zheng/comments/commentRss/339846.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/alex-zheng/services/trackbacks/339846.html</trackback:ping><description><![CDATA[     摘è¦: 上周åŽÖM¸€å®¶å…¬å”R¢è¯•,其中一个é¢è¯•题是这æ ïLš„åQŒåˆ¤æ–­ä¸‹é¢ç¨‹åºè¾“出,本äh很æ¯å…ïLš„写了"changed" Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ -->public class StringArgTest ...  <a href='http://www.aygfsteel.com/alex-zheng/articles/339846.html'>阅读全文</a><img src ="http://www.aygfsteel.com/alex-zheng/aggbug/339846.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/alex-zheng/" target="_blank">alex_zheng</a> 2010-12-05 16:27 <a href="http://www.aygfsteel.com/alex-zheng/articles/339846.html#Feedback" target="_blank" style="text-decoration:none;">å‘表评论</a></div>]]></description></item><item><title>netty3.2.3æºç åˆ†æž--æœåŠ¡å™¨ç«¯å‘逿•°æ®åˆ†æž?/title><link>http://www.aygfsteel.com/alex-zheng/articles/339795.html</link><dc:creator>alex_zheng</dc:creator><author>alex_zheng</author><pubDate>Sat, 04 Dec 2010 06:54:00 GMT</pubDate><guid>http://www.aygfsteel.com/alex-zheng/articles/339795.html</guid><wfw:comment>http://www.aygfsteel.com/alex-zheng/comments/339795.html</wfw:comment><comments>http://www.aygfsteel.com/alex-zheng/articles/339795.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/alex-zheng/comments/commentRss/339795.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/alex-zheng/services/trackbacks/339795.html</trackback:ping><description><![CDATA[上一½‹‡åˆ†æžäº†æœåŠ¡å™¨ç«¯è¯Õd–客户å‘é€çš„æ•°æ®åQŒè¿™½‹‡æ¥çœ‹æœåŠ¡å™¨ç«¯å¦‚ä½•å‘逿•°æ®ç»™å®¢æˆ·ç«¯ï¼ŒæœåС噍往外å‘逿•°æ®æ˜¯é€šè¿‡downstreamhandler从下åˆîC¸Šæ‰§è¡Œ<br /> å‘é€ä»ŽChannelFuture future = e.getChannel().write(response)开始执行Channels下的<br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> ChannelFuture write(Channel channel, Object message, SocketAddress remoteAddress) {<br />         ChannelFuture future </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> future(channel);<br />         channel.getPipeline().sendDownstream(<br />                 </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> DownstreamMessageEvent(channel, future, message, remoteAddress));<br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> future;<br />  }<br /> <br /> </span></div> telentpipeline中最下é¢ä¸€ä¸ªdownstreamhandler是stringencoderåQŒæœ€åŽæ‰§è¡ŒOneToOneEncoderçš„handleDownstream<br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> handleDownstream(<br />             ChannelHandlerContext ctx, ChannelEvent evt) </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> Exception {<br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">(evt </span><span style="color: rgb(0, 0, 255);">instanceof</span><span style="color: rgb(0, 0, 0);"> MessageEvent)) {<br />             ctx.sendDownstream(evt);<br />             </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br />         }<br /> <br />         MessageEvent e </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (MessageEvent) evt;<br />         Object originalMessage </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> e.getMessage();<br />         Object encodedMessage </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> encode(ctx, e.getChannel(), originalMessage);<br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (originalMessage </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> encodedMessage) {<br />             ctx.sendDownstream(evt);<br />         } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (encodedMessage </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">˜q™é‡Œå†™encodeæ•°æ®åQŒDefaultChannelPipelineçš„sendDownstream</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">            write(ctx, e.getFuture(), encodedMessage, e.getRemoteAddress());<br />         }<br />     }</span></div> DefaultChannelPipelineçš„sendDownstreamæ–ÒŽ³•<br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> sendDownstream(ChannelEvent e) {<br />             DefaultChannelHandlerContext prev </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> getActualDownstreamContext(</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.prev);<br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (prev </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />                 </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />                     </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">因䨓stringencoder是唯一一个downstreamhandleråQŒè¿™é‡Œæ‰§è¡ŒNioServerSocketPipelineSink.eventSunk</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                    getSink().eventSunk(DefaultChannelPipeline.</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">, e);<br />                 } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Throwable t) {<br />                     notifyHandlerException(e, t);<br />                 }<br />             } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />                 DefaultChannelPipeline.</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.sendDownstream(prev, e);<br />             }<br />         }</span></div> eventSunkæ–ÒŽ³•会执è¡?br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> handleAcceptedSocket(ChannelEvent e) {<br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (e </span><span style="color: rgb(0, 0, 255);">instanceof</span><span style="color: rgb(0, 0, 0);"> ChannelStateEvent) {<br />             ChannelStateEvent event </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (ChannelStateEvent) e;<br />             NioSocketChannel channel </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (NioSocketChannel) event.getChannel();<br />             ChannelFuture future </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> event.getFuture();<br />             ChannelState state </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> event.getState();<br />             Object value </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> event.getValue();<br /> <br />             </span><span style="color: rgb(0, 0, 255);">switch</span><span style="color: rgb(0, 0, 0);"> (state) {<br />             </span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);"> OPEN:<br />                 </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (Boolean.FALSE.equals(value)) {<br />                     channel.worker.close(channel, future);<br />                 }<br />                 </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />             </span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);"> BOUND:<br />             </span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);"> CONNECTED:<br />                 </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (value </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />                     channel.worker.close(channel, future);<br />                 }<br />                 </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />             </span><span style="color: rgb(0, 0, 255);">case</span><span style="color: rgb(0, 0, 0);"> INTEREST_OPS:<br />                 channel.worker.setInterestOps(channel, future, ((Integer) value).intValue());<br />                 </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />             }<br />         } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (e </span><span style="color: rgb(0, 0, 255);">instanceof</span><span style="color: rgb(0, 0, 0);"> MessageEvent) {<br />             MessageEvent event </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (MessageEvent) e;<br />             NioSocketChannel channel </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (NioSocketChannel) event.getChannel();<br />             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">攑օ¥writerequestqueue队列</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">            </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> offered </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> channel.writeBuffer.offer(event);<br />             </span><span style="color: rgb(0, 0, 255);">assert</span><span style="color: rgb(0, 0, 0);"> offered;<br />             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">执行nioworkerçš„writeFromUserCode,ä¹‹åŽæ‰§è¡Œwrite0æ–ÒŽ³•</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">            channel.worker.writeFromUserCode(channel);<br />         }<br />     }</span></div> <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> write0(NioSocketChannel channel) {<br />         </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> open </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />         </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> addOpWrite </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />         </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> removeOpWrite </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br /> <br />         </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> writtenBytes </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br /> <br />         </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> SocketSendBufferPool sendBufferPool </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.sendBufferPool;<br />         </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> SocketChannel ch </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> channel.socket;<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">之剞®†channel攑ֈ°äº†è¯¥é˜Ÿåˆ—</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> Queue</span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);">MessageEvent</span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> writeBuffer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> channel.writeBuffer;<br />         //<span style="color: rgb(80, 255, 90);"><span style="color: rgb(0, 134, 33);"><span style="color: rgb(80, 255, 90);"><span style="color: rgb(0, 134, 33);">默认ž®è¯•16‹Æ¡å†™</span></span></span></span><br />         </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> writeSpinCount </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> channel.getConfig().getWriteSpinCount();<br />         </span><span style="color: rgb(0, 0, 255);">synchronized</span><span style="color: rgb(0, 0, 0);"> (channel.writeLock) {<br />             channel.inWriteNowLoop </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />             </span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);"> (;;) {<br />                 MessageEvent evt </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> channel.currentWriteEvent;<br />                 SendBuffer buf;<br />                 </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (evt </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">从writebuffer中获得一个writeevent</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ((channel.currentWriteEvent </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> evt </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> writeBuffer.poll()) </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />                         removeOpWrite </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />                         channel.writeSuspended </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />                         </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />                     }<br />                     <br />                     channel.currentWriteBuffer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> buf </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> sendBufferPool.acquire(evt.getMessage());<br />                 } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />                     buf </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> channel.currentWriteBuffer;<br />                 }<br /> <br />                 ChannelFuture future </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> evt.getFuture();<br />                 </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />                     </span><span style="color: rgb(0, 0, 255);">long</span><span style="color: rgb(0, 0, 0);"> localWrittenBytes </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />                     </span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> i </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> writeSpinCount; i </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">; i </span><span style="color: rgb(0, 0, 0);">--</span><span style="color: rgb(0, 0, 0);">) {<br />                         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">å‘逿•°æ®ç»™å®¢æˆ·ç«?执行PooledSendBuffer.transferTo</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                        localWrittenBytes </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> buf.transferTo(ch);<br />                         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (localWrittenBytes </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">) {<br />                             writtenBytes </span><span style="color: rgb(0, 0, 0);">+=</span><span style="color: rgb(0, 0, 0);"> localWrittenBytes;<br />                             </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />                         }<br />                         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (buf.finished()) {<br />                             </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />                         }<br />                     }<br /> <br />                     </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (buf.finished()) {<br />                         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Successful write - proceed to the next message.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                        buf.release();<br />                         channel.currentWriteEvent </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />                         channel.currentWriteBuffer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />                         evt </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />                         buf </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />                         future.setSuccess();<br />                     } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />                         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Not written fully - perhaps the kernel buffer is full.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                        addOpWrite </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />                         channel.writeSuspended </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br /> <br />                         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (localWrittenBytes </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">) {<br />                             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Notify progress listeners if necessary.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                            future.setProgress(<br />                                     localWrittenBytes,<br />                                     buf.writtenBytes(), buf.totalBytes());<br />                         }<br />                         </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />                     }<br />                 } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (AsynchronousCloseException e) {<br />                     </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Doesn't need a user attention - ignore.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Throwable t) {<br />                     buf.release();<br />                     channel.currentWriteEvent </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />                     channel.currentWriteBuffer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />                     buf </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />                     evt </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />                     future.setFailure(t);<br />                     fireExceptionCaught(channel, t);<br />                     </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (t </span><span style="color: rgb(0, 0, 255);">instanceof</span><span style="color: rgb(0, 0, 0);"> IOException) {<br />                         open </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />                         close(channel, succeededFuture(channel));<br />                     }<br />                 }<br />             }<br />             channel.inWriteNowLoop </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />         }<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">触å‘写完æˆäº‹ä»Óž¼Œæ‰§è¡Œçš„æ˜¯DefaultChannelPipelineçš„sendUpstreamåQŒæœ€åŽè°ƒç”¨SimpleChannelUpstreamHandler.writeComplete<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">pipeline中的upstreamhandlerçš„writeComplete都未é‡å†™åQŒæ‰€ä»¥åªæ˜¯ç®€å•的传递该事äšg</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        fireWriteComplete(channel, writtenBytes);<br /> <br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (open) {<br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (addOpWrite) {<br />                 setOpWrite(channel);<br />             } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (removeOpWrite) {<br />                 clearOpWrite(channel);<br />             }<br />         }<br />     }<br /> </span></div> <img src ="http://www.aygfsteel.com/alex-zheng/aggbug/339795.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/alex-zheng/" target="_blank">alex_zheng</a> 2010-12-04 14:54 <a href="http://www.aygfsteel.com/alex-zheng/articles/339795.html#Feedback" target="_blank" style="text-decoration:none;">å‘表评论</a></div>]]></description></item><item><title>netty3.2.3æºç åˆ†æž--æœåŠ¡å™¨ç«¯è¯ÀL•°æ®åˆ†æž?/title><link>http://www.aygfsteel.com/alex-zheng/articles/339751.html</link><dc:creator>alex_zheng</dc:creator><author>alex_zheng</author><pubDate>Fri, 03 Dec 2010 13:26:00 GMT</pubDate><guid>http://www.aygfsteel.com/alex-zheng/articles/339751.html</guid><wfw:comment>http://www.aygfsteel.com/alex-zheng/comments/339751.html</wfw:comment><comments>http://www.aygfsteel.com/alex-zheng/articles/339751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/alex-zheng/comments/commentRss/339751.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/alex-zheng/services/trackbacks/339751.html</trackback:ping><description><![CDATA[上一½‹‡åˆ†æžäº†serverboostrapçš„å¯åŠ¨ï¼ŒæŽ¥ä¸‹æ¥åˆ†æžnetty的数æ®è¯»å–ã€?br /> 在nioworker的,负责è¯Õd–æ“作是由åQŒåœ¨è¯¥æ–¹æ³•中åQŒå¦‚果当å‰channelçš?readyOps & SelectionKey.OP_READ) != 0 || readyOps == 0åQŒä¸”此时<br /> ch.read(buff)<0,则判断客æˆïL«¯å·²ç»æ–­å¼€˜qžæŽ¥<span style="color: rgb(0, 0, 0);"><br /> </span> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> read(SelectionKey k) {<br />         </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> SocketChannel ch </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (SocketChannel) k.channel();<br />         </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> NioSocketChannel channel </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (NioSocketChannel) k.attachment();<br /> <br />         </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> ReceiveBufferSizePredictor predictor </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"><br />             channel.getConfig().getReceiveBufferSizePredictor();<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">默认1024个字节空é—?/span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> predictedRecvBufSize </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> predictor.nextReceiveBufferSize();<br /> <br />         </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> ret </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />         </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> readBytes </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />         </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> failure </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">分酘qžç®‹çš?024个byte½Iºé—´</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        ByteBuffer bb </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> recvBufferPool.acquire(predictedRecvBufSize);<br />         </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />             </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> ((ret </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ch.read(bb)) </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">) {<br />                 readBytes </span><span style="color: rgb(0, 0, 0);">+=</span><span style="color: rgb(0, 0, 0);"> ret;<br />                 </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">bb.hasRemaining()) {<br />                     </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />                 }<br />             }<br />             failure </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />         } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (ClosedChannelException e) {<br />             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Can happen, and does not need a user attention.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Throwable t) {<br />             fireExceptionCaught(channel, t);<br />         }<br /> <br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (readBytes </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">) {<br />             bb.flip();<br /> <br />             </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> ChannelBufferFactory bufferFactory </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"><br />                 channel.getConfig().getBufferFactory();<br />             </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> ChannelBuffer buffer </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> bufferFactory.getBuffer(readBytes);<br />             buffer.setBytes(</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">, bb);<br />             buffer.writerIndex(readBytes);<br /> <br />             recvBufferPool.release(bb);<br /> <br />             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Update the predictor.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">            predictor.previousReceiveBufferSize(readBytes);<br /> <br />             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">è§¦å‘æ¶ˆæ¯æŽ¥æ”¶äº‹äšgåQŒæ ¹æ®pipeline中upstreamhandlerç”׃¸ŠåˆîC¸‹çš„顺åºï¼Œè°ƒç”¨messageReceivedæ–ÒŽ³•</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">            fireMessageReceived(channel, buffer);<br />         } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />             recvBufferPool.release(bb);<br />         }<br /> <br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (ret </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">||</span><span style="color: rgb(0, 0, 0);"> failure) {<br />             close(channel, succeededFuture(channel));<br />             </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />         }<br /> <br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />     }</span></div> <span style="color: rgb(0, 0, 0);">     </span><span style="color: rgb(0, 0, 0);"><br /> </span> <br /> 在pipelinefactory中的½W¬ä¸€ä¸ªupstreamhandler为DelimiterBasedFrameDecoderåQŒç‘ô承自FrameDecoder <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> ChannelPipeline getPipeline() </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> Exception {<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Create a default pipeline implementation.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        ChannelPipeline pipeline </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> pipeline();<br /> <br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Add the text line codec combination first,</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        pipeline.addLast(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">framer</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> DelimiterBasedFrameDecoder(<br />                 </span><span style="color: rgb(0, 0, 0);">8192</span><span style="color: rgb(0, 0, 0);">, Delimiters.lineDelimiter()));<br />         pipeline.addLast(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">decoder</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> StringDecoder());<br />         pipeline.addLast(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">encoder</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> StringEncoder());<br /> <br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> and then business logic.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        pipeline.addLast(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">handler</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> TelnetServerHandler());<br /> <br />         </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> pipeline;<br />     }</span></div> 会调用FrameDecoderçš„messageReceived<br />  <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> messageReceived(<br />             ChannelHandlerContext ctx, MessageEvent e) </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> Exception {<br /> <br />         Object m </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> e.getMessage();<br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">(m </span><span style="color: rgb(0, 0, 255);">instanceof</span><span style="color: rgb(0, 0, 0);"> ChannelBuffer)) {<br />             ctx.sendUpstream(e);<br />             </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br />         }<br /> <br />         ChannelBuffer input </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (ChannelBuffer) m;<br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">input.readable()) {<br />             </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br />         }<br /> <br />         ChannelBuffer cumulation </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cumulation(ctx);<br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (cumulation.readable()) {<br />             cumulation.discardReadBytes();<br />             cumulation.writeBytes(input);<br />             callDecode(ctx, e.getChannel(), cumulation, e.getRemoteAddress());<br />         } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">˜q™é‡Œè°ƒç”¨å­ç±»çš„decodeæ–ÒŽ³•</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">            callDecode(ctx, e.getChannel(), input, e.getRemoteAddress());<br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (input.readable()) {<br />                 cumulation.writeBytes(input);<br />             }<br />         }<br />     }</span></div> <br />  //在这个upstreamhandlerä¸­ï¼Œä¼šä¸€ç›´è¯»å–æ•°æ®ï¼Œç›´åˆ°é‡åˆ°åè®®¾U¦å®šçš„ç»“æŸæ ‡å¿—扞®†messagereceived事äšg传给下一ä¸?br />  <br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> callDecode(<br />             ChannelHandlerContext context, Channel channel,<br />             ChannelBuffer cumulation, SocketAddress remoteAddress) </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> Exception {<br /> <br />         </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> (cumulation.readable()) {<br />             </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> oldReaderIndex </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> cumulation.readerIndex();<br />             Object frame </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> decode(context, channel, cumulation);<br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (frame </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />                 </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (oldReaderIndex </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> cumulation.readerIndex()) {<br />                     </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Seems like more data is required.<br />                     </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Let us wait for the next notification.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                    </span><span style="color: rgb(0, 0, 255);">break</span><span style="color: rgb(0, 0, 0);">;<br />                 } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />                     </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Previous data has been discarded.<br />                     </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Probably it is reading on.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                    </span><span style="color: rgb(0, 0, 255);">continue</span><span style="color: rgb(0, 0, 0);">;<br />                 }<br />             } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (oldReaderIndex </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> cumulation.readerIndex()) {<br />                 </span><span style="color: rgb(0, 0, 255);">throw</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> IllegalStateException(<br />                         </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">decode() method must read at least one byte </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"><br />                         </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">if it returned a frame (caused by: </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> getClass() </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />             }<br />             </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">ž®†messagereceive事äšg传给下个upstreamhandler</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">            unfoldAndFireMessageReceived(context, remoteAddress, frame);<br />         }<br />     }</span></div> 看孾cÈš„decode是如何判断数æ®è¯»å–完æ¯?br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">protected</span><span style="color: rgb(0, 0, 0);"> Object decode(<br />             ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) </span><span style="color: rgb(0, 0, 255);">throws</span><span style="color: rgb(0, 0, 0);"> Exception {<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Try all delimiters and choose the delimiter which yields the shortest frame.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> minFrameLength </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Integer.MAX_VALUE;<br />         ChannelBuffer minDelim </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">获å–\r\n的佾|?/span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);"> (ChannelBuffer delim: delimiters) {<br />             </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> frameLength </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> indexOf(buffer, delim);<br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (frameLength </span><span style="color: rgb(0, 0, 0);">>=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&&</span><span style="color: rgb(0, 0, 0);"> frameLength </span><span style="color: rgb(0, 0, 0);"><</span><span style="color: rgb(0, 0, 0);"> minFrameLength) {<br />                 minFrameLength </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> frameLength;<br />                 minDelim </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> delim;<br />             }<br />         }<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">如果扑ֈ°\r\nåQŒè¡¨æ˜Žå®¢æˆïL«¯æ•°æ®å‘é€å®Œæ¯?/span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (minDelim </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />             </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> minDelimLength </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> minDelim.capacity();<br />             ChannelBuffer frame;<br /> <br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (discardingTooLongFrame) {<br />                 </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> We've just finished discarding a very large frame.<br />                 </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Go back to the initial state.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                discardingTooLongFrame </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />                 buffer.skipBytes(minFrameLength </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> minDelimLength);<br /> <br />                 </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> TODO Let user choose when the exception should be raised - early or late?<br />                 </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">      If early, fail() should be called when discardingTooLongFrame is set to true.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> tooLongFrameLength </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.tooLongFrameLength;<br />                 </span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.tooLongFrameLength </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />                 fail(ctx, tooLongFrameLength);<br />                 </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />             }<br /> <br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (minFrameLength </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> maxFrameLength) {<br />                 </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Discard read frame.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                buffer.skipBytes(minFrameLength </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> minDelimLength);<br />                 fail(ctx, minFrameLength);<br />                 </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />             }<br /> <br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (stripDelimiter) {<br />                 </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">˜q™é‡Œè¯Õd–全部数æ®</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                frame </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> buffer.readBytes(minFrameLength);<br />                 buffer.skipBytes(minDelimLength);<br />             } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />                 frame </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> buffer.readBytes(minFrameLength </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> minDelimLength);<br />             }<br /> <br />             </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> frame;<br />         } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">discardingTooLongFrame) {<br />                 </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (buffer.readableBytes() </span><span style="color: rgb(0, 0, 0);">></span><span style="color: rgb(0, 0, 0);"> maxFrameLength) {<br />                     </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Discard the content of the buffer until a delimiter is found.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                    tooLongFrameLength </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> buffer.readableBytes();<br />                     buffer.skipBytes(buffer.readableBytes());<br />                     discardingTooLongFrame </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />                 }<br />             } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />                 </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Still discarding the buffer since a delimiter is not found.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">                tooLongFrameLength </span><span style="color: rgb(0, 0, 0);">+=</span><span style="color: rgb(0, 0, 0);"> buffer.readableBytes();<br />                 buffer.skipBytes(buffer.readableBytes());<br />             }<br />             </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br />         }<br />     }</span></div> 因䨓unfold默认是falseåQŒä¼šæ‰§è¡ŒåQŒè°ƒç”¨ä¸‹ä¸€ä¸ªupstreamhandleråQŒè¿™é‡Œæ˜¯stringdecoderåQŒé€šè¿‡stringdecoderåQŒå°†channelbuffer中的数æ®è½¬äØ“string<br /> ç„¶åŽå†è§¦å‘下一个upstreamhandlerçš„messagereceiveåQŒè¿™é‡Œæ˜¯TelnetServerHandler<br /> <div style="background-color: rgb(238, 238, 238); font-size: 13px; border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; width: 98%;"><!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> messageReceived(<br />             ChannelHandlerContext ctx, MessageEvent e) {<br /> <br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Cast to a String first.<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> We know it is a String because we put some codec in TelnetPipelineFactory.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        String request </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (String) e.getMessage();<br /> <br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Generate and write a response.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        String response;<br />         </span><span style="color: rgb(0, 0, 255);">boolean</span><span style="color: rgb(0, 0, 0);"> close </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />         </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (request.length() </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">) {<br />             response </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Please type something.</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">r</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />         } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (request.toLowerCase().equals(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">bye</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)) {<br />             response </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Have a good day!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">r</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />             close </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">;<br />         } </span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"> {<br />             response </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Did you say '</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> request </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">'?</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">r</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />         }<br /> <br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> We do not need to write a ChannelBuffer here.<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> We know the encoder inserted at TelnetPipelineFactory will do the conversion.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        ChannelFuture future </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> e.getChannel().write(response);<br /> <br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> Close the connection after sending 'Have a good day!'<br />         </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> if the client has sent 'bye'.</span><span style="color: rgb(0, 128, 0);"><br /> </span><span style="color: rgb(0, 0, 0);">        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (close) {<br />             future.addListener(ChannelFutureListener.CLOSE);<br />         }<br />     }</span></div> <br /> æ•°æ®è¯Õd–分æžå®Œæ¯•åQŒæŽ¥ç€¾l§ç®‹åˆ†æžæœåŠ¡å™¨ç«¯æ•°æ®çš„å‘é€?br /> <br /> <br /> <img src ="http://www.aygfsteel.com/alex-zheng/aggbug/339751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/alex-zheng/" target="_blank">alex_zheng</a> 2010-12-03 21:26 <a href="http://www.aygfsteel.com/alex-zheng/articles/339751.html#Feedback" target="_blank" style="text-decoration:none;">å‘表评论</a></div>]]></description></item><item><title>netty3.2.3æºç åˆ†æž--ServerBootstrapå¯åŠ¨åˆ†æžhttp://www.aygfsteel.com/alex-zheng/articles/339552.htmlalex_zhengalex_zhengWed, 01 Dec 2010 13:37:00 GMThttp://www.aygfsteel.com/alex-zheng/articles/339552.htmlhttp://www.aygfsteel.com/alex-zheng/comments/339552.htmlhttp://www.aygfsteel.com/alex-zheng/articles/339552.html#Feedback0http://www.aygfsteel.com/alex-zheng/comments/commentRss/339552.htmlhttp://www.aygfsteel.com/alex-zheng/services/trackbacks/339552.html阅读全文

alex_zheng 2010-12-01 21:37 å‘表评论
]]>
jboss5.1+mysql5+spring3æ•°æ®åº“jndié…ç½®http://www.aygfsteel.com/alex-zheng/articles/339204.htmlalex_zhengalex_zhengSat, 27 Nov 2010 08:58:00 GMThttp://www.aygfsteel.com/alex-zheng/articles/339204.htmlhttp://www.aygfsteel.com/alex-zheng/comments/339204.htmlhttp://www.aygfsteel.com/alex-zheng/articles/339204.html#Feedback0http://www.aygfsteel.com/alex-zheng/comments/commentRss/339204.htmlhttp://www.aygfsteel.com/alex-zheng/services/trackbacks/339204.html

1.ž®†mysqlçš„JDBC驱动攑ֈ°çš„JBOSS_HOME\server\default\lib ä¸?wbr>

2.把JBOSS_HOME\docs\examples\jca\mysql-ds.xmlå¤åˆ¶åˆ°JBOSS_HOME\server\default\deploy目录下。修改mysql- ds.xmlæ–‡äšg
 <local-tx-datasource>
    
<jndi-name>mysql</jndi-name>
    
<connection-url>jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf-8</connection-url>
    
<driver-class>com.mysql.jdbc.Driver</driver-class>
    
<user-name>alex</user-name>
    
<password>alex</password>
    <use-java-context>false</use-java-context> 
    
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
   

    
<!--pooling parameters-->
    
<min-pool-size>5</min-pool-size>
    
<max-pool-size>100</max-pool-size>
    
<blocking-timeout-millis>5000</blocking-timeout-millis>
    
<idle-timeout-minutes>15</idle-timeout-minutes>
    
<set-tx-query-timeout/>
    
<query-timeout>60</query-timeout> <!-- maximum of 1 minutes for queries -->

    
<!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
    
<metadata>
       
<type-mapping>mySQL</type-mapping>
    
</metadata>

3.springé…置文äšgä¸?br />
    <!--在mysql-ds.xml中设¾|?/span>use-java-context为falseå?æ³¨æ„æ²¡æœ‰å‰ç¼€javaåQ?->
    <
jee:jndi-lookup id="dataSource" jndi-name="mysql" />
    
<bean id="txManager"
        class
="org.springframework.transaction.jta.JtaTransactionManager">
       <!--手动注入åQŒå¦åˆ™ä¼šæŠ¥transactionmanager not bound-->
        
<property name="transactionManagerName" value="java:/TransactionManager"/>
    
</bean>
è‡Ïx­¤åQŒspring3使用jbossçš„jta事务½Ž¡ç†å·²ç»é…置完毕ã€?br />
é—留问题åQ?br /> 如果使用默认讄¡½®use-java-context为trueåQŒç„¶åŽä‹É用jndi name为java:mysql,æç¤ºmysql not boundåQŒå¾ˆå¥‡æ€ªï¼Œåœ¨jbosså¯åŠ¨çš„æ—¶å€™å¯ä»¥çœ‹åˆ°å°†mysql¾l‘定
到命å空间java:mysql




alex_zheng 2010-11-27 16:58 å‘表评论
]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ÔúêãÌØÆì| Ì©°²ÊÐ| ¼ÃÄÏÊÐ| ¼ÎÀèÏØ| ³£ÄþÊÐ| º×¸ÚÊÐ| ºé½­ÊÐ| ƽÂÞÏØ| ÄÏÀÖÏØ| ×ÊÐËÊÐ| ÐðÓÀÏØ| ÍͲýÏØ| êùÎªÏØ| Î÷ÇàÇø| Ëç·ÒºÓÊÐ| ÓñÌïÏØ| ¿ªÆ½ÊÐ| ÒÁÎáÏØ| Î÷³ëÏØ| ¶¡ÇàÏØ| Ê®ÑßÊÐ| ·á³ÇÊÐ| ºÓÇúÏØ| Çú¾¸ÊÐ| É«´ïÏØ| ÜÝÆ½ÏØ| ÁÉÄþÊ¡| ÇíÖÐ| ½Ò¶«ÏØ| µ¤ÑôÊÐ| ÑÓ°²ÊÐ| Âé³ÇÊÐ| ÉÌÂåÊÐ| ÈêÄÏÏØ| ±£¶¨ÊÐ| äðºÓÊÐ| Íû³ÇÏØ| µ¤ÀâÏØ| ¶¨±ßÏØ| ãòÎ÷ÏØ| ¿ËÀ­ÂêÒÀÊÐ|