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