problems on service multi-clients with length field based frames

"Trustin Lee (이희승)" trustin at gmail.com
Tue Jan 26 10:38:56 EST 2010


Hi XuQing,

You have to use Bootstrap.setPipelineFactory() instead of
Bootstrap.getPipeline() because a LengthFieldBasedFrameDecoder can
handle only one channel.

Actually, it's always recommended to use Bootstrap.setPipelineFactory().
 Previous examples were somewhat misleading.  To see it in action, take
a look into the Factorial example:


http://www.jboss.org/file-access/default/members/netty/freezone/xref/3.2/org/jboss/netty/example/factorial/FactorialClient.html

All other examples and Javadoc have been updated to reduce user
confusion and will be deployed at next release (3.2.0.ALPHA4).

HTH,
Trustin

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

-- 
what we call human nature in actuality is human habit
http://gleamynode.net/


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 260 bytes
Desc: OpenPGP digital signature
Url : http://lists.jboss.org/pipermail/netty-users/attachments/20100127/9fd51b79/attachment.bin 


More information about the netty-users mailing list