Use and analysis of Linebasedframedecoder decoder in Netty: Solving the problem of TCP sticky packet

Source: Internet
Author: User
Tags throwable

[TOC]

Use and analysis of Linebasedframedecoder decoder in Netty: Solving the problem of TCP sticky packet

The previous article "Netty in TCP sticky packet problem code example and analysis" demonstrates the use of a time server example demonstrates the problem of TCP sticky packet, which is used LineBasedFrameDecoder to solve the problem.

However, it is important to note that the LineBasedFrameDecoder name is known for its meaning, it is related to the line, and in the previous presentation of the TCP sticky packet problem, the author is intentionally in the message sent to add a line break, the purpose is to explain in the later LineBasedFrameDecoder use, of course, also gives a simple solution to the problem of the TCP sticky packet, Or a simple case to give us learners a more intuitive understanding.

The code came from chapter 4th of the Netty authoritative guide, but I still made some changes.

Service-Side Code Timeserver.java
Package Cn.xpleaf.netty02;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 {        Configure the NIO thread group on the service side eventloopgroup Bossgroup = new Nioeventloopgroup ();        Eventloopgroup Workergroup = new Nioeventloopgroup ();            try {serverbootstrap b = new Serverbootstrap (); B.group (Bossgroup, Workergroup). Channel (nioserversocketchannel.class). Option (channeloption .            So_backlog, 1024x768). Childhandler (New Childchannelhandler ());   Bind port, synchronization waits for success         Channelfuture f = b.bind (port). sync ();        Wait for the service-side listener port to close F.channel (). Closefuture (). sync ();            } finally {//gracefully exits, releasing thread pool resource bossgroup.shutdowngracefully ();        Workergroup.shutdowngracefully (); }} Private class Childchannelhandler extends Channelinitializer<socketchannel> {@Override prot ected void Initchannel (Socketchannel ch) throws Exception {//core in two lines below, added Linebasedframedecoder and Stringdecoder two Decoder//So when the message arrives at our business processing handler that is Timerserverhandler, the message that is seen//is the result of the previous two decoders being processed ch.pipeline (            ). AddLast (New Linebasedframedecoder (1024));            Ch.pipeline (). AddLast (New Stringdecoder ());        Ch.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 (port);            } catch (NumberFormatException e) {//Todo:handle exception}} new    Timeserver (). bind (port); }}
Timeserverhandler.java
Package Cn.xpleaf.netty02;import Java.sql.date;import Io.netty.buffer.bytebuf;import io.netty.buffer.Unpooled; Import Io.netty.channel.channelhandleradapter;import Io.netty.channel.channelhandlercontext;import    Io.netty.channel.channelinboundhandleradapter;public class Timeserverhandler extends Channelinboundhandleradapter {    private int counter = 0; @Override public void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {String BODY = (Strin        g) msg; The role of counter is to mark the number of times a client has received a request 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.write (RESP); } @Override public void Channelreadcomplete (Channelhandlercontext ctx) throws Exception {Ctx.flush ();    } @Override public void Exceptioncaught (Channelhandlercontext ctx, throwable cause) {ctx.close (); }}
Client code Timeclient.java
Package Cn.xpleaf.netty02;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 {//Configure client NIO thread Group Eventloopgroup group = new Nioeventloopgroup ();            try {Bootstrap b = new Bootstrap (); B.group (Group). Channel (niosocketchannel.class). Option (Channeloption.tcp_nodelay, true). Han Dler (New channelinitializer<socketchannel> () {@Override protected void Initch              Annel (Socketchannel ch) throws Exception {          Core in the following two lines, added Linebasedframedecoder and stringdecoder two decoder//So when the message arrives our business processing handler namely Timerserv Erhandler, the messages you see//are the result of the previous two decoders being processed ch.pipeline (). AddLast (New LINEBASEDFR                        Amedecoder (1024));                        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 {//gracefully exits, releasing the NIO thread Group group.shutdowngracefully ();        }} public static void Main (string[] args) throws Exception {int port = 8080;            if (args! = null && args.length > 0) {try {port = integer.valueof (port); } catch (NumberFormatException e) {//with default}} new TImeclient (). Connect (port, "localhost"); }}
Timeclienthandler.java
Package Cn.xpleaf.netty02;import Java.util.logging.logger;import Io.netty.buffer.bytebuf;import Io.netty.buffer.unpooled;import Io.netty.channel.channelhandleradapter;import Io.netty.channel.channelhandlercontext;import Io.netty.channel.channelinboundhandleradapter;public Class Timeclienthandler extends Channelinboundhandleradapter {private static final Logger Logger = Logger.getlogger (TimeServ    ErHandler.class.getName ());    private int counter;    Private byte[] req;    Public Timeclienthandler () {req = ("QUERY time ORDER" + system.getproperty ("Line.separator")). GetBytes ();        } @Override public void channelactive (Channelhandlercontext ctx) {BYTEBUF message = NULL;            for (int i = 0; i < i++) {message = Unpooled.buffer (req.length);            Message.writebytes (req);        Ctx.writeandflush (message); }} @Override public void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {String bod y = (String) msg; Counter's role is to mark this as the number of times a client request is received SYSTEM.OUT.PRINTLN ("Now is:" + body + ";    The counter is: "+ ++counter); } @Override public void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {Logger        . Warning ("Unexpected exception from downstream:");    Ctx.close (); }}
Test

Server Run Results:

The time server receive order : QUERY TIME ORDER ; the counter is : 1The time server receive order : QUERY TIME ORDER ; the counter is : 2The time server receive order : QUERY TIME ORDER ; the counter is : 3...省略多行...The time server receive order : QUERY TIME ORDER ; the counter is : 98The time server receive order : QUERY TIME ORDER ; the counter is : 99The time server receive order : QUERY TIME ORDER ; the counter is : 100

Client Run Results:

Now is : 2018-02-11 ; the counter is : 1Now is : 2018-02-11 ; the counter is : 2Now is : 2018-02-11 ; the counter is : 3...省略多行...Now is : 2018-02-11 ; the counter is : 98Now is : 2018-02-11 ; the counter is : 99Now is : 2018-02-11 ; the counter is : 100

As can be seen from the output, this does solve the problem of TCP sticky packets.

Principle Analysis

The following analysis comes from the book, which is also posted here:

Use and analysis of Linebasedframedecoder decoder in Netty: Solving the problem of TCP sticky packet

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.