problems on service multi-clients with length field based frames

XuQing Tan missedone at gmail.com
Tue Jan 26 10:21:45 EST 2010


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          |
 -----------------------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/netty-users/attachments/20100126/2fcab0c2/attachment-0001.html 


More information about the netty-users mailing list