The example in chapter three is generally no problem with functional testing, but there is a sticky/unpacking problem when the pressure comes up or when a large message is sent.
Then you need to use Linebasedframedecoder+stringdecoder
Client side request changed to 100 consecutive times
Package Com.xiaobing.netty.fourth;
Import java.net.SocketAddress;
Import Org.omg.CORBA.Request;
Import Io.netty.buffer.ByteBuf;
Import io.netty.buffer.Unpooled;
Import Io.netty.channel.ChannelHandler;
Import Io.netty.channel.ChannelHandlerAdapter;
Import Io.netty.channel.ChannelHandlerContext;
Import io.netty.channel.ChannelPromise;
public classTimeclienthandlerExtends Channelhandleradapter {
private static final Logger logger= new Logger.getlogger (Timeclienthandler.class);
private int counter;
Private byte[] req;
Public Timeclienthandler () {
Req = ("QUERY Time ORDER" +system.getproperty ("Line.separator")). GetBytes ();
}
/*
* Client and server TCP link established successfully after being called
* @see io.netty.channel.channelhandleradapter#channelactive (io.netty.channel.ChannelHandlerContext)
*/
@Override
public void Channelactive (Channelhandlercontext ctx) throws Exception {
Send a request message to the server
Bytebuf messagebuf = null;
The following situation occurs when a TCP sticky packet
for (int i=0; i<100; i++) {
Messagebuf = Unpooled.buffer (req.length);
Messagebuf.writebytes (req);
Ctx.writeandflush (MESSAGEBUF);
}
}
/*
* Called when the service side returns a reply message
* @see Io.netty.channel.channelhandleradapter#channelread (Io.netty.channel.ChannelHandlerContext, Java.lang.Object)
*/
@Override
public void Channelread (Channelhandlercontext ctx, Object msg)
Throws Exception {
// Bytebuf buf = (bytebuf) msg;
// byte[] req = new byte[buf.readablebytes ()];
// Buf.readbytes (req);
// String bodystring = new String (req, "UTF-8");
String bodystring = (string) msg;
System.out.println ("Now is:" + bodystring + "; The count is: "+ ++counter);
}
@Override
public void Exceptioncaught (Channelhandlercontext ctx, throwable cause)
Throws Exception {
Ctx.close ();
}
}
Package Com.xiaobing.netty.fourth;
Import Java.security.acl.Group;
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;
public class Timeclient {
public void Connect (int port, String host) throws exception{
Eventloopgroup Group = new Nioeventloopgroup ();
try{
Client-initiated helper classes
Bootstrap B = new Bootstrap ();
B.group (Group). Channel (Niosocketchannel.class)
. option (Channeloption.tcp_nodelay, True)
. Handler (new channelinitializer<socketchannel> () {
Setting Channelhandler to Channelpipeline at initialization time
@Override
protected void Initchannel (Socketchannel ch) throws Exception {
Ch.pipeline (). AddLast (New Linebasedframedecoder (1024));
Ch.pipeline (). AddLast (New Stringdecoder ());
Ch.pipeline (). AddLast (New Timeclienthandler ());
}
});
Initiating an asynchronous connection
Channelfuture f = b.connect (Host,port). sync ();
Waiting for client link to close
F.channel (). Closefuture (). sync ();
}finally{
Group.shutdowngracefully ();
}
}
public static void Main (string[] args) throws Exception {
int port = 8080;
New Timeclient (). Connect (port, "127.0.0.1");
}
}
Server Side
Package Com.xiaobing.netty.fourth;
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;
public class Timeserver {
public void bind (int port) throws exception{
System.out.println ("-------timeserver start----------");
The server accepts the client's connection thread
Eventloopgroup Bossgroup = new Nioeventloopgroup ();
Network read-write thread
Eventloopgroup Workergroup = new Nioeventloopgroup ();
Server-side Secondary startup class
Serverbootstrap B = new Serverbootstrap ();
try {
B.group (Bossgroup, Workergroup). Channel (Nioserversocketchannel.class)
. option (Channeloption.so_backlog, 1024)
. Childhandler (New Childchannelhandler ());
Blocking waits for port bindings to complete
System.out.println ("-------timeserver wait----------");
Channelfuture f = b.bind (port). sync ();
Waiting for service-side link to close
F.channel (). Closefuture (). sync ();
}finally{
Bossgroup.shutdowngracefully ();
Workergroup.shutdowngracefully ();
}
}
Network IO Processing class
Private class Childchannelhandler extends channelinitializer<socketchannel>{
@Override
protected void Initchannel (Socketchannel arg0) throws Exception {
Cases where a TCP sticky packet occurs
// Arg0.pipeline (). AddLast (New Timeserverhandler ());
System.out.println ("-------childchannelhandler----------");
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;
New Timeserver (). bind (port);
}
}
Package Com.xiaobing.netty.fourth;
Import Io.netty.buffer.ByteBuf;
Import io.netty.buffer.Unpooled;
Import Io.netty.channel.ChannelHandlerAdapter;
Import Io.netty.channel.ChannelHandlerContext;
Read and Write network events
public class Timeserverhandler extends Channelhandleradapter {
private int counter;
@Override
public void Channelread (Channelhandlercontext ctx, Object msg) throws exception{
// Bytebuf buf = (bytebuf) msg;
// Gets the number of buffer readable bytes
// 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 ());
String BODY = (string) msg;
System.out.println ("The time server receive order:" + body + "; The count is: "+ ++counter);
String currenttimestring = "QUERY time ORDER". Equalsignorecase (body), New Java.util.Date (System.currenttimemillis ()). ToString (): "Bad ORDER";
currenttimestring = currenttimestring + system.getproperty ("Line.separator");
Reply message
Bytebuf resp = Unpooled.copiedbuffer (Currenttimestring.getbytes ());
Ctx.writeandflush (RESP);
}
@Override
public void Channelreadcomplete (Channelhandlercontext ctx) {
Writes messages from the message send queue to Socketchannel
Ctx.flush ();
}
@Override
public void Exceptioncaught (Channelhandlercontext ctx,throwable cause) {
When an exception occurs, close CTX
Ctx.close ();
}
}
Netty Authoritative Guide--------The fourth chapter on the problem of TCP sticky packet/unpacking