I. Description of the TCP Sticky pack/unpacking problem,
Two. Failure to consider a TCP sticky packet causes a feature exception case
In accordance with the original design, the server should receive 100 query time instruction request query, the client should print 100 times the server's system time
1. Service-side class
Package Com.phei.netty.s2016042302;import Io.netty.bootstrap.serverbootstrap;import Io.netty.channel.channelfuture;import Io.netty.channel.channelinitializer;import io.netty.channel.ChannelOption; Import Io.netty.channel.eventloopgroup;import Io.netty.channel.nio.nioeventloopgroup;import Io.netty.channel.socket.socketchannel;import Io.netty.channel.socket.nio.nioserversocketchannel;import Io.netty.handler.codec.linebasedframedecoder;import io.netty.handler.codec.string.stringdecoder;/** * Service side * @author RENHJ * */public class Timeserver {public void bind (int port) throws exception{//the first user server receives a connection from a client Eventloopgroup Bossgroup = new Nioeventloopgroup ();//second user Socketchannel network read-write Eventloopgroup workergroup = new Nioeventloopgroup (); try{//Create Serverbootstrap object, start the secondary startup class Serverbootstrap B = new Serverbootstrap () on the NIO server; B.group (Bossgroup, Workergroup). Set to NIO Channel (nioserversocketchannel.class). Option (Channeloption.so_backlog, 1024).Childhandler (New Childchannelhandler ()); Bind port, synchronization waits successfully channelfuture F = b.bind (port). sync (); Wait for the server listening port to close F.channel (). Closefuture (). sync (); }finally{//Release thread pool resource bossgroup.shutdowngracefully (); Workergroup.shutdowngracefully (); }}private class Childchannelhandler extends channelinitializer<socketchannel>{@Overrideprotected void Initchannel (Socketchannel arg0) throws Exception {Arg0.pipeline (). AddLast (New Timeserverhandler ());}} public static void Main (string[] args) throws Exception {int port = 8080;if (args! = null && args.length>0) {try{ Port = integer.valueof (Args[0]);} catch (Exception e) {//takes the default value}}new timeserver (). bind (port);}}
2. Service-side core processing class
Package Com.phei.netty.s2016042302;import Java.util.date;import Io.netty.buffer.bytebuf;import Io.netty.buffer.unpooled;import Io.netty.channel.channelhandleradapter;import io.netty.channel.channelhandlercontext;/** * Service-side core processing class * @author RENHJ * */public class Timeserverhandler extends Channelh Andleradapter {private int counter; @Overridepublic void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {bytebuf buf = (bytebuf) msg;byte [] req = new Byte[buf.readablebytes ()];buf.readbytes (req); String BODY = new String (req, "UTF-8"). Substring (0,req.length-system.getproperty ("Line.separator"). Length ()); System.out.println ("The time server receive order:" + body+ "; The counter is:" + ++counter); String currenttime = "QUERY time ORDER". Equalsignorecase (body)? New Date (System.currenttimemillis ()). ToString (): "Bad ORDER "; currenttime = CurrentTime +system.getproperty (" Line.separator "); Bytebuf resp = Unpooled.copiedbuffer (Currenttime.getbytes ()); Ctx.writeandflush (RESP);} @Overridepublic void Channelreadcomplete (Channelhandlercontext ctx) throws Exception {Ctx.flush ();} @Overridepublic void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {Ctx.close ();}}
3. Client class
Package Com.phei.netty.s2016042302;import Io.netty.bootstrap.bootstrap;import io.netty.channel.ChannelFuture; Import Io.netty.channel.channelinitializer;import Io.netty.channel.channeloption;import Io.netty.channel.eventloopgroup;import Io.netty.channel.nio.nioeventloopgroup;import Io.netty.channel.socket.socketchannel;import Io.netty.channel.socket.nio.niosocketchannel;import Io.netty.handler.codec.linebasedframedecoder;import io.netty.handler.codec.string.stringdecoder;/** * Service side * @author RENHJ * */public class Timeclient {public void connect (int port, String host) throws exception{//Configure client NiO thread Group Eventloopgrou P Group = new Nioeventloopgroup (), try{bootstrap B = new Bootstrap (); B.group (group). Channel (Niosocketchannel.class). Option (Channeloption.tcp_nodelay, True). Handler (new channelinitializer<socketchannel> () {@Overridepublic void Initchannel (Socketchannel ch) throws Exception{ch.pipeline (). AddLast (New Timeclienthandler ());}); /initiates an asynchronous connection operation channelfuture F = b.connect (host, Port). sYnc (); Wait for the client link to close F.channel (). Closefuture (). sync (); finally{//Release NIO thread group.shutdowngracefully ();}} public static void Main (string[] args) throws Exception{int port = 8080;if (args!=null && args.length>0) {Try{po RT = Integer.valueof (Args[0]);} catch (Exception e) {}}new timeclient (). Connect (port, "127.0.0.1");}}
4. Client core Processing class
Package Com.phei.netty.s2016042302;import Io.netty.buffer.bytebuf;import Io.netty.buffer.unpooled;import Io.netty.channel.channelhandleradapter;import io.netty.channel.channelhandlercontext;/** * Client core processing class * @author RENHJ * */public class Timeclienthandler extends Channelhandleradapter {private int counter;private byte[] Req;public Timeclienthandler () {req = ("QUERY Time ORDER" +system.getproperty ("Line.separator")). GetBytes (); @Overridepublic void Channelactive (Channelhandlercontext ctx) throws Exception {Bytebuf message = null;for (int i=0;i< 100;i++) {message = Unpooled.buffer (req.length); Message.writebytes (req); Ctx.writeandflush (message);}} @Overridepublic void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {bytebuf buf = (bytebuf) msg;byte [] req = new Byte[buf.readablebytes ()];buf.readbytes (req); String BODY = new String (req, "UTF-8"); System.out.println ("Now is:" +body + "; The counter is: "+ ++counter);} @Overridepublic void Exceptioncaught (ChannelhandlercontextCTX, Throwable cause) throws Exception {//Release resources ctx.close ();}}
5. Running Results
Three. Solve the problem of TCP sticky packets with Linebasedframedecoder+stringdecoder (line break)
1. Service-side class
Package Com.phei.netty.s20160423;import Io.netty.bootstrap.serverbootstrap;import io.netty.channel.ChannelFuture; Import Io.netty.channel.channelinitializer;import Io.netty.channel.channeloption;import Io.netty.channel.eventloopgroup;import Io.netty.channel.nio.nioeventloopgroup;import Io.netty.channel.socket.socketchannel;import Io.netty.channel.socket.nio.nioserversocketchannel;import Io.netty.handler.codec.linebasedframedecoder;import io.netty.handler.codec.string.stringdecoder;/** * Service side * @author RENHJ * */public class Timeserver {public void bind (int port) throws exception{//the first user server receives a connection from a client Eventloopgroup Bossgroup = new Nioeventloopgroup ();//second user Socketchannel network read-write Eventloopgroup workergroup = new Nioeventloopgroup (); try{//Create Serverbootstrap object, start the secondary startup class Serverbootstrap B = new Serverbootstrap () on the NIO server; B.group (Bossgroup, Workergroup). Set to NIO Channel (nioserversocketchannel.class). Option (Channeloption.so_backlog, 1024x768). ChIldhandler (New Childchannelhandler ()); Bind port, synchronization waits successfully channelfuture F = b.bind (port). sync (); Wait for the server listening port to close F.channel (). Closefuture (). sync (); }finally{//Release thread pool resource bossgroup.shutdowngracefully (); Workergroup.shutdowngracefully (); }}private class Childchannelhandler extends channelinitializer<socketchannel>{@Overrideprotected void Initchannel (Socketchannel arg0) throws Exception {//Resolve TCP Sticky Pack problem Arg0.pipeline (). AddLast (New Linebasedframedecoder (1024 ); Arg0.pipeline (). AddLast (New Stringdecoder ()); Arg0.pipeline (). AddLast (New Timeserverhandler ());}} public static void Main (string[] args) throws Exception {int port = 8080;if (args! = null && args.length>0) {try{ Port = integer.valueof (Args[0]);} catch (Exception e) {//takes the default value}}new timeserver (). bind (port);}}
2. Service-side core processing class
Package Com.phei.netty.s20160423;import Java.util.date;import Io.netty.buffer.bytebuf;import Io.netty.buffer.unpooled;import Io.netty.channel.channelhandleradapter;import io.netty.channel.channelhandlercontext;/** * Service-side core processing class * @author RENHJ * */public class Timeserverhandler extends Channelh Andleradapter {private int counter; @Overridepublic void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {string body = (string) msg; System.out.println ("The time server receive order:" + body+ "; The counter is:" + ++counter); String currenttime = "QUERY time ORDER". Equalsignorecase (body)? New Date (System.currenttimemillis ()). ToString (): "Bad ORDER "; currenttime = CurrentTime +system.getproperty (" Line.separator "); Bytebuf resp = Unpooled.copiedbuffer (Currenttime.getbytes ()); Ctx.writeandflush (RESP);} @Overridepublic void Channelreadcomplete (Channelhandlercontext ctx) throws Exception {Ctx.flush ();} @Overridepublic void Exceptioncaught (Channelhandlercontext ctx, throwable cause) tHrows Exception {ctx.close ();}}
3. Client class
Package Com.phei.netty.s20160423;import Io.netty.bootstrap.bootstrap;import Io.netty.channel.channelfuture;import Io.netty.channel.channelinitializer;import Io.netty.channel.channeloption;import Io.netty.channel.EventLoopGroup ; Import Io.netty.channel.nio.nioeventloopgroup;import Io.netty.channel.socket.socketchannel;import Io.netty.channel.socket.nio.niosocketchannel;import Io.netty.handler.codec.linebasedframedecoder;import io.netty.handler.codec.string.stringdecoder;/** * Client * @author RENHJ * */public class Timeclient {public void connect (int Port, String host) throws exception{//configuration client NiO thread Group Eventloopgroup group = new Nioeventloopgroup (); Try{bootstrap B = new Bo Otstrap (); B.group (group). Channel (niosocketchannel.class). Option (Channeloption.tcp_nodelay, True). Handler (new Channelinitializer<socketchannel> () {@Overridepublic void Initchannel (Socketchannel ch) throws exception{// Resolve TCP Sticky packet problems Ch.pipeline (). AddLast (New Linebasedframedecoder (1024x768)); Ch.pipeline (). AddLast (New Stringdecoder ()); Ch.pipeline (). AddLast (New Timeclienthandler ());}); /initiates an asynchronous connection operation channelfuture F = b.connect (host, port). sync (); Wait for the client link to close F.channel (). Closefuture (). sync (); finally{//Release NIO thread group.shutdowngracefully ();}} public static void Main (string[] args) throws Exception{int port = 8080;if (args!=null && args.length>0) {Try{po RT = Integer.valueof (Args[0]);} catch (Exception e) {}}new timeclient (). Connect (port, "127.0.0.1");}}
4. Client core Processing class
Package Com.phei.netty.s20160423;import Io.netty.buffer.bytebuf;import Io.netty.buffer.unpooled;import Io.netty.channel.channelhandleradapter;import io.netty.channel.channelhandlercontext;/** * Client core processing class * @author RENHJ * */public class Timeclienthandler extends Channelhandleradapter {private int counter;private byte[] Req;public Timeclienthandler () {req = ("QUERY Time ORDER" +system.getproperty ("Line.separator")). GetBytes (); @Overridepublic void Channelactive (Channelhandlercontext ctx) throws Exception {Bytebuf message = null;for (int i=0;i< 100;i++) {message = Unpooled.buffer (req.length); Message.writebytes (req); Ctx.writeandflush (message);}} @Overridepublic void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {string body = (string) msg; System.out.println ("Now is:" +body + "; The counter is: "+ ++counter);} @Overridepublic void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {//Release resources ctx.close ();}}
5. Operation result, perfect solution
Netty Learning of TCP sticky/unpacking