Hi, trustin<br><br>thanks for your reply, which bright me up<br><br>finally i found there are two problems in my code:<br>1. the first, i use the default pipeline, as you pointed<br>2. second, you know that i use spring to inject a list of handler instance into the server instance, once the server instance is created, the handlers instance are created too, and in my pipeline factory, i &quot;reuse&quot; the same handler instance, which cause the same pb as using default pipeline <br>

<br>some suggestion:<br>1. at the first time when i saw @ChannelPipelineCoverage(&quot;one&quot;), i really confused. after reading some netty source code, i find that this annotation is used to indicate the handler is some kind &quot;singleton&quot; or not, i mean, if a handler is annotated with @ChannelPipelineCoverage(&quot;one&quot;), the handler is intended to be created new instance every time in the getPipeline() of the Pipeline factory, right?<br>

i also remember that you talked about this annotation in some previous mails, personally, i think, add some &quot;singleton&quot; key word into annotation name may be much easier to understand<br><br>2. after i read some netty source code, that i found the pipelinefactory.getPipeline() will be called again and again once new connection/session is created, but i did not find and clue in the document/javadoc? so if there&#39;s some place mention the pipeline factory life-cycle could help?<br>

<br>anyway, netty is still a agile framework help us developing simple tcp application in seconds.<br><br><br clear="all">  Thanks &amp; Best Regards!<br><br>               ///<br>              (. .)<br>  --------ooO--(_)--Ooo--------<br>

  |         Nick Tan          |<br>  -----------------------------<br><br>
<br><br><div class="gmail_quote">On Tue, Jan 26, 2010 at 7:38 AM, &quot;Trustin Lee (이희승)&quot; <span dir="ltr">&lt;<a href="mailto:trustin@gmail.com">trustin@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

Hi XuQing,<br>
<br>
You have to use Bootstrap.setPipelineFactory() instead of<br>
Bootstrap.getPipeline() because a LengthFieldBasedFrameDecoder can<br>
handle only one channel.<br>
<br>
Actually, it&#39;s always recommended to use Bootstrap.setPipelineFactory().<br>
 Previous examples were somewhat misleading.  To see it in action, take<br>
a look into the Factorial example:<br>
<br>
<br>
<a href="http://www.jboss.org/file-access/default/members/netty/freezone/xref/3.2/org/jboss/netty/example/factorial/FactorialClient.html" target="_blank">http://www.jboss.org/file-access/default/members/netty/freezone/xref/3.2/org/jboss/netty/example/factorial/FactorialClient.html</a><br>


<br>
All other examples and Javadoc have been updated to reduce user<br>
confusion and will be deployed at next release (3.2.0.ALPHA4).<br>
<br>
HTH,<br>
<font color="#888888">Trustin<br>
</font><div><div></div><div class="h5"><br>
XuQing Tan wrote:<br>
&gt; Hi, trustin<br>
&gt;<br>
&gt; I recently write a dummy server which parse length field based frames, and<br>
&gt; it works fine only on single client and single request,<br>
&gt; it failed while i have clients below:<br>
&gt; 1. if it&#39;s single thread, in which there&#39;s a &quot;for&quot; loop send several request<br>
&gt; to server<br>
&gt; 2. if it&#39;s multi-thread, in which send several request to server<br>
&gt; the server side, or more precisely, the corresponding sessions are blocked<br>
&gt; for ever and the EchoHandler never invoked<br>
&gt;<br>
&gt; it both occurred on <a href="http://3.1.5.GA" target="_blank">3.1.5.GA</a> and 3.2.0 trunk<br>
&gt;<br>
&gt; the server side code looks like:<br>
&gt;<br>
&gt; {code}<br>
&gt;         ChannelFactory factory = new<br>
&gt; NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors<br>
&gt;                 .newCachedThreadPool());<br>
&gt;<br>
&gt;         ServerBootstrap bootstrap = new ServerBootstrap(factory);<br>
&gt;         ChannelPipeline pipeline = bootstrap.getPipeline();<br>
&gt;<br>
&gt;         pipeline.addLast(&quot;codec&quot;, new<br>
&gt; org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder());<br>
&gt;         pipeline.addLast(&quot;handler&quot;, new EchoHandler());<br>
&gt; {code}<br>
&gt;<br>
&gt; it&#39;s really simple<br>
&gt;<br>
&gt; the client side code are straightforward, it sends length field based frame<br>
&gt; (the length field indicate the full frame length include the length of<br>
&gt; length), and receive the response data, which is same as the request data.<br>
&gt;<br>
&gt; could you kindly have a look?<br>
&gt;<br>
&gt;<br>
&gt; * single thread with multi-request client *<br>
&gt; {code}<br>
&gt; public class SingleThreadClient {<br>
&gt;<br>
&gt;     public static void main(String[] args) throws Exception {<br>
&gt;         for (int i = 0; i &lt; 100; i++) {<br>
&gt;             byte[] dataBuf = new byte[1850 + i];<br>
&gt;             Arrays.fill(dataBuf, (byte) i);<br>
&gt;<br>
&gt;             Socket client = new Socket(&quot;localhost&quot;, 4040);<br>
&gt;             DataOutputStream req = new<br>
&gt; DataOutputStream(client.getOutputStream());<br>
&gt;             DataInputStream resp = new<br>
&gt; DataInputStream(client.getInputStream());<br>
&gt;             int datalen = dataBuf.length + 4;<br>
&gt;             req.writeInt(datalen);<br>
&gt;<br>
&gt;             int offset = 0;<br>
&gt;             int left = dataBuf.length;<br>
&gt;             while (left &gt; 0) {<br>
&gt;                 int length = Math.min(1024, left);    // split it into multi<br>
&gt; small fragments<br>
&gt;                 req.write(dataBuf, offset, length);<br>
&gt;                 offset += length;<br>
&gt;                 left -= length;<br>
&gt;             }<br>
&gt;             req.flush();<br>
&gt;<br>
&gt;             int len = resp.readInt();<br>
&gt;             byte[] byResp = new byte[len - 4];<br>
&gt;             resp.read(byResp);<br>
&gt;             System.out.println(i + &quot; resp data len: &quot; + byResp.length);<br>
&gt;<br>
&gt;             client.close();<br>
&gt;         }<br>
&gt;     }<br>
&gt;<br>
&gt; }<br>
&gt; {code}<br>
&gt;<br>
&gt;<br>
&gt; * multi thread client *<br>
&gt; {code}<br>
&gt; public class MultiThreadClient {<br>
&gt;<br>
&gt;     public static void main(String[] args) throws Exception {<br>
&gt;         ExecutorService exec = Executors.newFixedThreadPool(20);<br>
&gt;         for (int i = 0; i &lt; 100; i++) {<br>
&gt;             exec.execute(new SocketTestClient(i));<br>
&gt;         }<br>
&gt;     }<br>
&gt;<br>
&gt;     private static class SocketTestClient implements Runnable {<br>
&gt;<br>
&gt;         private int initVal;<br>
&gt;<br>
&gt;         public SocketTestClient(int initVal) {<br>
&gt;             this.initVal = initVal;<br>
&gt;         }<br>
&gt;<br>
&gt;         public void run() {<br>
&gt;             try {<br>
&gt;                 byte[] dataBuf = new byte[1850 + initVal];<br>
&gt;                 Arrays.fill(dataBuf, (byte) initVal);<br>
&gt;<br>
&gt;                 Socket client = new Socket(&quot;localhost&quot;, 4040);<br>
&gt;                 DataOutputStream req = new<br>
&gt; DataOutputStream(client.getOutputStream());<br>
&gt;                 DataInputStream resp = new<br>
&gt; DataInputStream(client.getInputStream());<br>
&gt;                 int datalen = dataBuf.length + 4;<br>
&gt;                 req.writeInt(datalen);<br>
&gt;<br>
&gt;                 int offset = 0;<br>
&gt;                 int left = dataBuf.length;<br>
&gt;                 while (left &gt; 0) {<br>
&gt;                     int length = Math.min(1024, left);<br>
&gt;                     req.write(dataBuf, offset, length);<br>
&gt;                     offset += length;<br>
&gt;                     left -= length;<br>
&gt;                 }<br>
&gt;                 req.flush();<br>
&gt;<br>
&gt;                 int len = resp.readInt();<br>
&gt;                 byte[] byResp = new byte[len - 4];<br>
&gt;                 resp.read(byResp);<br>
&gt;                 System.out.println(initVal + &quot; resp data len: &quot; +<br>
&gt; byResp.length);<br>
&gt;<br>
&gt;                 client.close();<br>
&gt;             } catch (Exception e) {<br>
&gt;                 e.printStackTrace();<br>
&gt;             }<br>
&gt;         }<br>
&gt;     }<br>
&gt; }<br>
&gt; {code}<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;  Thanks &amp; Best Regards!<br>
&gt;<br>
&gt;               ///<br>
&gt;              (. .)<br>
&gt;  --------ooO--(_)--Ooo--------<br>
&gt;  |         Nick Tan          |<br>
&gt;  -----------------------------<br>
&gt;<br>
&gt;<br>
&gt;<br>
</div></div>&gt; ------------------------------------------------------------------------<br>
<div class="im">&gt;<br>
&gt; _______________________________________________<br>
&gt; netty-users mailing list<br>
&gt; <a href="mailto:netty-users@lists.jboss.org">netty-users@lists.jboss.org</a><br>
&gt; <a href="https://lists.jboss.org/mailman/listinfo/netty-users" target="_blank">https://lists.jboss.org/mailman/listinfo/netty-users</a><br>
<br>
</div><div><div></div><div class="h5">--<br>
what we call human nature in actuality is human habit<br>
<a href="http://gleamynode.net/" target="_blank">http://gleamynode.net/</a><br>
<br>
<br>
</div></div><br>_______________________________________________<br>
netty-users mailing list<br>
<a href="mailto:netty-users@lists.jboss.org">netty-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/netty-users" target="_blank">https://lists.jboss.org/mailman/listinfo/netty-users</a><br></blockquote></div><br>