Netty (c) TCP sticky packet unpacking processing

Source: Internet
Author: User
Tags ftp protocol

TCP is a "flow" protocol, a complete package may be split into multiple packets by TCP to send, or the small package into a large packet sent, which is called the TCP sticky packet and unpacking problems.

Sticky bag, unpacking problem description

Assuming that the client sends packets D1 and D2 to the server individually, the following 4 scenarios may exist because the number of bytes read by the server is indeterminate.

    • 1. The service end points 2 times to read two separate packages, namely D1,D2, no sticky bags and unpacking;
    • 2. The service side received two packets at a time, D1 and D2 glued together, was become the TCP sticky packet;
    • 3. The service end points 2 reads to two packets, the first time reads to the complete D1 and the D2 packet the partial content, the second time reads to the D2 package the remainder, this is called the unpacking;
    • 4. The service end points 2 reads to two packets, first reads to the partial D1, reads the D1 remainder and the complete D2 packet for the second time;

If at this time the server TCP receive sliding window is very small, and the packet D1 and D2 are very large, it is likely to send a fifth possibility, that is, the service side multiple times to the D1 and D2 receive completely, during several times the unpacking situation. (TCP receive sliding window: is the size of the receiver, with the size of the traffic changes, if my explanation is not clear, please readers themselves Baidu, or check the "computer network", "TCP/IP" TCP content)

solution strategy of sticky bag problem

Because the underlying TCP is unable to understand the upper layer of business logic, so at the bottom is not able to ensure that the packet is not split and reorganization, this problem can only be solved by the upper layer of application protocol stack design, according to the industry's mainstream protocol solution, summarized as follows:

    • 1. Message length, for example, the size of each message is a fixed length of 200 bytes, if not enough, empty space to fill;
    • 2. Add a carriage return newline at the end of the package to split, such as the FTP protocol;
    • 3. Divide the message into the message header and the message body, the message header contains a field representing the total message length (or message length), usually the design idea is the first field of the message header with int to represent the total length of the message; (This is what I used to do with Linux C).
    • 4. More complex application-layer protocols;

In order to solve the problem of TCP sticky packet unpacking, Netty provides a number of encoders to handle by default, the following is illustrated by code;

Service side:

1  Public classTimeserver {2 /*--------The same code as the Netty introductory chapter--------*/3     Private classChildchannelhandlerextendsChannelinitializer<socketchannel>{4 @Override5         protected  voidInitchannel (Socketchannel arg0)throwsexception{6             //add Linebasedframedecoder and Stringdecoder encoders7Arg0.pipeline (). AddLast (NewLinebasedframedecoder (1024));8Arg0.pipeline (). AddLast (NewStringdecoder ());9Arg0.pipeline (). AddLast (NewTimeserverhandler ());Ten         } One     } A  - /*--------The same code as the Netty introductory chapter--------*/ -}
1  Public classTimeserverhandlerextendschannelhandleradapter{2 3     Private intcounter;4 5     //Read and write operations for the network6 @Override7      Public voidchannelread (channelhandlercontext ctx,object msg)8             throwsexception{9 TenString BODY =(String) msg; OneSystem.out.println ("The Time server Order:" + body+ "; The counter is:" + (+ +)counter)); A  -String currenttime = "QUERY time ORDER". Equalsignorecase (body)?NewDate ( -System.currenttimemillis ()). ToString (): "Bad ORDER"; theCurrentTime +=system.getproperty ("Line.separator");//system.getproperty ("Line.separator"), obtaining the role of/n -Bytebuf resp =Unpooled.copiedbuffer (Currenttime.getbytes ()); - Ctx.writeandflush (resp); -  +         //after TCP success is established between the client and the server, Netty's NIO thread calls Channelactive -         //Send the command for the query time to the server.  +         //Call Channelhandlercontext's Writeandflush method to send the request message to the server A         //when the server responds, the Channelread method is called at     } -  - @Override -      Public voidexceptioncaught (Channelhandlercontext ctx,throwable cause) { - ctx.close (); -     } in}

Customer Service side

1  Public classtimeclient {2      Public voidConnect (String Host,intPortthrowsexception{3         //Configure the NIO thread group on the service side4Eventloopgroup Group =NewNioeventloopgroup ();5 6         Try {7             //Bootstrap class, which is the secondary startup class that initiates the NIO server8Bootstrap B =NewBootstrap ();9B.group (Group). Channel (Niosocketchannel.class)Ten. Option (Channeloption.tcp_nodelay,true) One. Handler (NewChannelinitializer<socketchannel>() { A @Override -                          Public voidinitchannel (socketchannel ch) -                                 throwsexception{ the                             //add Linebasedframedecoder and Stringdecoder encoders -Ch.pipeline (). AddLast (NewLinebasedframedecoder (1024)); -Ch.pipeline (). AddLast (NewStringdecoder ()); -Ch.pipeline (). AddLast (NewTimeclienthandler ()); +                         } -                     }); +  A             //initiating an asynchronous join operation atChannelfuture f=B.connect (host,port). sync (); -  -             //waiting for the service end link to close - F.channel (). Closefuture (). sync (); -}finally { - group.shutdowngracefully (); in         } -     } to  +      Public Static voidMain (String[]args)throwsexception{ -         intPort = 8080; the         if(args!=NULL&& args.length>0){ *             Try { $Port = integer.valueof (args[0]);Panax Notoginseng             } -             Catch(NumberFormatException ex) {} the         } +         NewTimeclient (). Connect ("127.0.0.1", port); A     } the}

The above code, mainly to increase the Linebasedframedecoder and Stringdecoder encoder to handle the sticky bag, unpacking problems. All project code, the source code under Src/main/java/nettystickypacket, is divided into the client and the service side, their codes basic and the Netty introductory chapter code similar, just adds the decoder.

Linebasedframedecoder and Stringdecoder Encoder description

Linebasedframedecoder working principle: Compile the bytebuf in order to see if there is a "\ n" or "\ r \ n", if so, at this position as the end position, from the readable index to the end of the interval of the byte is composed of a row. It is a decoder that ends with a newline character, supports either a carry terminator or no terminator, and supports the maximum length of a single line. If a newline character is still not found after continuous reading to the maximum length, an exception is thrown and the exception stream that was previously read is ignored.

Stringdecoder function: Converts the Received object to a string, and then continues to invoke the subsequent handler. The Linebasedframedecoder + stringdecoder composition is a text decoder that is switched by line and is designed to support TCP's sticky packets and unpacking.

Perhaps the reader will ask a new question: What if the message sent is not ended with a newline character? Or not a carriage return line feed, by the length field in the message header to subcontract what to do? Do you need to write your own half-pack decoder? The answer is no, Netty offers a variety of decoders that support TCP sticky/unpacking.

For a "delimiter decoder", the next chapter explains it separately.

SOURCE download GitHub Address: Https://github.com/orange1438/Netty_Course

Netty (c) TCP sticky packet unpacking processing

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.