Netty (ii) TCP sticky, unpacking, and UDP communications

Source: Internet
Author: User
Tags object serialization readable serialization throwable jboss
Netty Basic Implementation

Netty steps to implement communication:
1. Create two NIO thread groups, one for Network event processing (connections to accept clients), and another for network traffic reading and writing.
2. Create a Serverbootstrap object that configures a range of parameters for the Netty, such as accepting the cache size of outgoing data.
3. Create a class channelinitializer that is actually processed to prepare for initialization, such as setting up the character set that accepts outgoing data, the format, and the interface that actually processes the data.
4. Bind port, execute synchronous blocking method wait for server side to start.

public class Serverhandler extends channelhandleradapter{@Override public void Channelread (Channelhandlercontext
        CTX, Object msg) throws Exception {//((BYTEBUF) msg). Release ();
        Do something bytebuf buf = (bytebuf) msg;
        byte[] bytes = new Byte[buf.readablebytes ()];//readablebytes () readable data buf.readbytes (bytes);
        String request = new String (bytes, "Utf-8");

        System.out.println ("Server:" + request);
        Write to client String response = "Server-side response data: 888"; Ctx.write (Unpooled.copiedbuffer (Response.getbytes ()))//write method helps to release messages without finally releasing the message. AddListener ( Channelfuturelistener.close);
    Monitoring, the data sent after the active disconnect with the client connection Ctx.flush (); @Override public void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {CA
        Use.printstacktrace ();
    Ctx.close (); } public class Server {public static void main (string[] args) throws Interruptedexception {//1.A thread group is used to receive client-side connections Eventloopgroup Bossgroup = new Nioeventloopgroup ();
        2. The second thread group is used for the actual business process Eventloopgroup WorkGroup = new Nioeventloopgroup ();
        3. Create a helper class bootstrap, that is, a series of configuration to the server Serverbootstrap B = new Serverbootstrap (); B.group (Bossgroup, WorkGroup). Channel (Nioserversocketchannel.class). Childhandler (New channelinitializer& Lt Socketchannel> () {@Override protected void Initchannel (Socketchannel channel) throws Exceptio
            n {channel.pipeline (). AddLast (New Serverhandler ());

        }). Option (Channeloption.so_backlog, 128). Childoption (Channeloption.so_keepalive, true);
        Channelfuture future = B.bind (6666). sync ();
        Block Future.channel (). Closefuture (). sync ();
        Bossgroup.shutdowngracefully ();
    Workgroup.shutdowngracefully (); Extends channelhandleradapter{@Override public class ClientHandler void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {try {bytebuf buf = (bytebuf)
            Msg
            byte[] bytes = new Byte[buf.readablebytes ()];//readablebytes () readable data buf.readbytes (bytes);
            String request = new String (bytes, "Utf-8");
        System.out.println ("Client:" + request); finally {referencecountutil.release (msg);//Release Message}} @Override public void Exceptioncau
        Ght (Channelhandlercontext ctx, Throwable cause) throws Exception {cause.printstacktrace ();
    Ctx.close (); } public class Client {public static void main (string[] args) throws Exception {Eventloopgroup Group =
        New Nioeventloopgroup ();
        Bootstrap B = new Bootstrap ();

            B.group (Group). Channel (Niosocketchannel.class). Handler (new channelinitializer<socketchannel> () {
 protected void Initchannel (Socketchannel sc) throws Exception {               Sc.pipeline (). AddLast (New ClientHandler ());

        }
        });

        Channelfuture CF = B.connect ("127.0.0.1", 6666). sync ();
BUF//Cf.channel (). Write (Unpooled.copiedbuffer ("777". GetBytes ());
        Cf.channel (). Flush ();
        Cf.channel (). Writeandflush (Unpooled.copiedbuffer ("777". GetBytes ());
        Block Cf.channel (). Closefuture (). sync ();
    Group.shutdowngracefully (); }
}
TCP Sticky Pack, unpacking problem

TCP is a "stream" protocol, and the so-called flow is the genetic data without boundaries. The TCP bottom does not understand the specific meaning of the upper business data, it will follow the actual situation of the TCP Buffer Packet division, in the business, we a complete package may be TCP divided into multiple packets to send, may also be packaged into a large number of small packets into a big data packages sent out, this is the so-called TCP sticky packet, Unpacking issues.
TCP Sticky Pack, unpacking problem causes:
1. Application write writes a byte size greater than the size of the set interface send buffer
2. TCP Segmentation for MSS size
3. Ethernet frame payload greater than MTU for IP fragmentation

Sticky package, unpacking mainstream solution:
1. Message fixed length, for example, the size of each packet to 200 bytes, if not enough, empty fill space;
2. At the end of the package to add special characters for segmentation, such as the addition of carriage return;
3. Divide the message into the header and the body of the message, including the field that represents the total length of the message, and then handle the business logic

Netty solve the problem of sticky and unpacking:
1. Separator class Delimiterbasedframedecoder (custom separator)
2. Fixedlengthframedecoder (fixed length)

public class ServerHandler1 extends channelhandleradapter{@Override public void channelactive (Channelhandlercont
    Ext ctx) throws Exception {System.out.println ("Server channel active ...");
    @Override public void Channelreadcomplete (Channelhandlercontext ctx) throws Exception {} @Override public void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {string request = (string) msg
        ;
        System.out.println ("Server:" + request);
        String response = "Server-side response:" + msg + "$_";
    Ctx.writeandflush (Unpooled.copiedbuffer (Response.getbytes ())); @Override public void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {CA
        Use.printstacktrace ();
    Ctx.close (); } public class Server1 {public static void main (string[] args) throws Interruptedexception {//1. Create thread, receive
        Client Eventloopgroup Pgroup = new Nioeventloopgroup (); 2. Create a lineProcess for processing data transfer eventloopgroup Wgroup = new Nioeventloopgroup ();
        3. Create server helper class Serverbootstrap B = new Serverbootstrap (); B.group (Pgroup, Wgroup). Channel (nioserversocketchannel.class). Option (Channeloption.so_backlog, 1
            024). Option (Channeloption.so_sndbuf, 32*1024). Option (Channeloption.so_rcvbuf, 32*1024)
                . option (Channeloption.so_keepalive, True). Childhandler (New channelinitializer<socketchannel> () {
                    @Override protected void Initchannel (Socketchannel sc) throws Exception {
                    Set Special separator Bytebuf buf = Unpooled.copiedbuffer ("$_". GetBytes ());
                    Sc.pipeline (). AddLast (New Delimiterbasedframedecoder (1024, buf));
                    Sets the encoding Sc.pipeline (). AddLast (New Stringdecoder ()) in the form of a string.
                Sc.pipeline (). AddLast (New ServerHandler1 ()); }
            });
        4. Bound connection Channelfuture CF = B.bind (6666). sync ();
        Wait for the server listening port to close Cf.channel (). Closefuture (). sync ();
        Pgroup.shutdowngracefully ();
    Wgroup.shutdowngracefully (); The public class ClientHandler1 extends channelhandleradapter{@Override the public void channelactive (ChannelHandle
    Rcontext ctx) throws Exception {System.out.println ("Client active ...");
            @Override public void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {try {
            String response = (string) msg;
        SYSTEM.OUT.PRINTLN ("Client:" + msg); finally {referencecountutil.release (msg);//Release Message}} @Override public void Channelread Complete (Channelhandlercontext ctx) throws Exception {} @Override public void Exceptioncaught (ChannelHandle
    Rcontext CTX, Throwable cause) throws Exception {ctx.close (); } public class Client1 {public STAtic void Main (string[] args) throws Interruptedexception {//1. Create thread Group Eventloopgroup group = new Nioeventlo 
        Opgroup ();
        2. Create client-side helper class Bootstrap B = new Bootstrap (); 
            B.group (Group). Channel (Niosocketchannel.class). Handler (new channelinitializer<socketchannel> () { 
                @Override protected void Initchannel (Socketchannel sc) throws Exception {//Create separator
                Bytebuf buf = Unpooled.copiedbuffer ("$_". GetBytes ());
                Sc.pipeline (). AddLast (New Delimiterbasedframedecoder (1024,BUF));
                Sc.pipeline (). AddLast (New Stringdecoder ());
            Sc.pipeline (). AddLast (New ClientHandler1 ());

        }
        });
        3. Connection server Channelfuture CF = B.connect ("127.0.0.1", 6666). sync ();
        Cf.channel (). Writeandflush (Unpooled.wrappedbuffer ("Bbbb$_". GetBytes ());

        Cf.channel (). Writeandflush (Unpooled.wrappedbuffer ("Ccc$_". GetBytes ()); //Wait for the server listening port to close Cf.channel (). Closefuture (). sync ();
    Group.shutdowngracefully ();
 }
}
public class ServerHandler1 extends channelhandleradapter{@Override public void channelactive (Channelhandlercont
    Ext ctx) throws Exception {System.out.println ("Server channel active ..."); @Override public void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {String requ
        EST = (String) msg;
        SYSTEM.OUT.PRINTLN ("server:" + request);
        String response = Request;
    Ctx.writeandflush (Unpooled.copiedbuffer (Response.getbytes ()));
    @Override public void Channelreadcomplete (Channelhandlercontext ctx) throws Exception {} @Override
    public void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {ctx.close (); } public class Server1 {public static void main (string[] args) throws Interruptedexception {//1. Creating threads, managing
        Connection Eventloopgroup pgroup = new Nioeventloopgroup (); 2. Create threads, process data transfer eventloopgroup Wgroup = new NioevEntloopgroup ();
        3. Create service-side helper class Serverbootstrap B = new Serverbootstrap (); B.group (Pgroup, Wgroup). Channel (nioserversocketchannel.class). Option (Channeloption.so_backlog, 1
            024). Option (Channeloption.so_sndbuf, 32*1024). Option (Channeloption.so_rcvbuf, 32*1024)
                . option (Channeloption.so_keepalive, True). Childhandler (New channelinitializer<socketchannel> () {
                    @Override protected void Initchannel (Socketchannel sc) throws Exception {
                    Sets a fixed-length string to receive Sc.pipeline (). AddLast (New Fixedlengthframedecoder (5));
                    Sets the string form encoding Sc.pipeline (). AddLast (New Stringdecoder ());
                Sc.pipeline (). AddLast (New ServerHandler1 ());

        }
            });

        4. Binding port Channelfuture CF = B.bind (6666). sync ();
 Wait for the server listening port to close Cf.channel (). Closefuture (). sync ();       Pgroup.shutdowngracefully ();
    Wgroup.shutdowngracefully (); The public class ClientHandler1 extends channelhandleradapter{@Override the public void channelactive (ChannelHandle
    Rcontext ctx) throws Exception {System.out.println ("Client channel active ...");
            @Override public void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {try {
            String response = (string) msg;
        SYSTEM.OUT.PRINTLN ("Client:" + msg); finally {referencecountutil.release (msg);//Release Message}} @Override public void CHANNELREADC Omplete (Channelhandlercontext ctx) throws Exception {} @Override public void Exceptioncaught (Channelhandler
    Context CTX, Throwable cause) throws Exception {ctx.close ();
        } public class Client1 {public static void main (string[] args) throws Interruptedexception {//1. Creating threads Eventloopgroup Group = new Nioeventloopgroup();
        2. Create Auxiliary class Bootstrap B = new Bootstrap (); 
            B.group (Group). Channel (Niosocketchannel.class). Handler (new channelinitializer<socketchannel> () { @Override protected void Initchannel (Socketchannel sc) throws Exception {//Set fixed length Word
                The string receives Sc.pipeline (). AddLast (New Fixedlengthframedecoder (5));
                Sc.pipeline (). AddLast (New Stringdecoder ());
            Sc.pipeline (). AddLast (New ClientHandler1 ());

        }
        });
        3. Connect the service side channelfuture CF = B.connect ("127.0.0.1", 6666). sync ();
        Cf.channel (). Writeandflush (Unpooled.wrappedbuffer ("aaaabbbb". GetBytes ());

        Cf.channel (). Writeandflush (Unpooled.copiedbuffer ("CCCCCCC". GetBytes ());
        Wait for the client to close Cf.channel (). Closefuture (). sync ();
    Group.shutdowngracefully (); }
}
Netty Coding and decoding

You can use Java for object serialization, Netty to transfer, but there are many drawbacks to Java serialization, such as Java serialization is not cross-language, serialization after the stream is too large, serialization performance is too low, and so on.
Mainstream coding and decoding framework:
JBoss's marshalling Package
Google's Protobuf
The Kyro based on Protobuf
Messagepack Framework

Jboss marshalling is a Java object serialization package that optimizes the JDK default serialization framework while maintaining compatibility with the Java.io.Serializable interface while adding some tunable parameters and additional features.
Tool class

/** * Decompression Tool class * * public class Gziputil {private final static Logger Logger = Logger.getlogger (Gziputil.class); public static byte[] gzip (byte[] data) throws IOException {Bytearrayoutputstream BAOs = new Bytearrayoutputstre
        AM ();
        Gzipoutputstream gzipos = null;
        byte[] result = NULL;
            try {gzipos = new Gzipoutputstream (BAOs);
            Gzipos.write (data);
            Gzipos.finish ();
        result = Baos.tobytearray (); The catch (IOException e) {logger.error ("failed to compress the file.")
            ", e);
        throw new IOException ();
                finally {if (Gzipos!= null) {try {gzipos.close ();
                catch (IOException e) {e.printstacktrace ();
                } if (BAOs!= null) {try {baos.close ();
       catch (IOException e) {e.printstacktrace ();         } Gzipos = null;
        BAOs = null;
    return result; public static byte[] Ungzip (byte[] data throws IOException {Bytearrayinputstream Bais = new Bytearrayinpu
        Tstream (data);
        Gzipinputstream Gzipis = null;
        Bytearrayoutputstream BAOs = null;
        byte[] result = NULL;
            try {gzipis = new Gzipinputstream (Bais);
            byte[] buf = new byte[1024];
            int num =-1;
            BAOs = new Bytearrayoutputstream ();
            while (num = gzipis.read (buf, 0, Buf.length))!=-1) {baos.write (buf, 0, num);
            result = Baos.tobytearray ();
        Baos.flush (); The catch (IOException e) {logger.error ("Failed to extract the file.")
            ", e);
        throw new IOException ();
                finally {if (Gzipis!= null) {try {gzipis.close ();
      catch (IOException e) {              E.printstacktrace ();
                } if (Bais!= null) {try {bais.close ();
                catch (IOException e) {e.printstacktrace ();
                } if (BAOs!= null) {try {baos.close ();
                catch (IOException e) {e.printstacktrace ();
            } Gzipis = null;
            Bais = null;
        BAOs = null;
    return result; //test public static void main (string[] args) throws Exception {//file path String Readpath = System.
        GetProperty ("User.dir") + File.separator + "sources" + File.separator + "001.jpg";
        File File = new file (Readpath);
        FileInputStream fis = new FileInputStream (file);
        byte[] data = new byte[fis.available ()];
        Fis.read (data);

        Fis.close (); System.oUt.println ("File Original size:" + data.length);
        File compression byte[] result = gziputil.gzip (data);

        SYSTEM.OUT.PRINTLN ("File Compressed size:" + result.length);
        File decompression byte[] Ungzipfile = gziputil.ungzip (result);

        SYSTEM.OUT.PRINTLN ("File Decompression size:" + ungzipfile.length); Write file String Writepath = System.getproperty ("User.dir") + File.separator + "receive" + File.separator + "001.jpg"
        ;
        FileOutputStream fos = new FileOutputStream (Writepath);
        Fos.write (Ungzipfile);
    Fos.close (); }

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.