Mina, Netty, Twisted learn Together (iii): TCP prefix fixed-size message (Header)

Source: Internet
Author: User
Tags throwable

In the previous blog post, there is a way to introduce the wrapping of cut messages.

But there is a small problem, such a method, the message itself includes a newline character, that will be cut into two of the message. The result is not correct.

This article describes the second method of message cutting, which is 2nd in the previous blog post: Use a fixed length header that indicates the length of the body. The message is cut by specifying the number of bytes in the body with a header prefix of a fixed number of bytes.



The header in the figure above is fixed to 4 bytes, and the header holds a 4-byte (32-bit) integer, such as 12, which is 0x0000000c. This integer is used to specify the length of the body (in bytes). After reading so many bytes of body, it is the header of the next message.


The following respectively with Mina, Netty, twisted to achieve such a message to the relevance and decoding.


MINA:

Mina provides a prefixedstringcodecfactory to encode messages of this type for decoding. Prefixedstringcodecfactory The default header size is 4 bytes. Of course it can be specified as 1 or 2.

public class TCPServer {public static void main (string[] args) throws IOException {Ioacceptor acceptor = new Niosocketacce Ptor ();//The 4-byte header specifies the number of bytes in the body. The handling of such messages Acceptor.getfilterchain (). AddLast ("Codec", new Protocolcodecfilter (New Prefixedstringcodecfactory ( Charset.forname ("UTF-8"))); Acceptor.sethandler (new Tcpserverhandle ()); Acceptor.bind (new inetsocketaddress (8080) );}} Class Tcpserverhandle extends Iohandleradapter {@Overridepublic void Exceptioncaught (iosession session, Throwable cause ) throws Exception {Cause.printstacktrace ();} New data received @overridepublic void Messagereceived (iosession session, Object message) throws Exception {string msg = (string) m Essage; System.out.println ("messagereceived:" + msg); @Overridepublic void Sessioncreated (Iosession session) throws Exception {System.out.println ("sessioncreated");} @Overridepublic void Sessionclosed (Iosession session) throws Exception {System.out.println ("sessionclosed");}}

Netty:

Netty uses Lengthfieldbasedframedecoder to handle such messages.

The new Lengthfieldbasedframedecoder (80, 0, 4, 0, 4) in the following code includes 5 parameters, each of which is int maxframelength, int lengthfieldoffset, int lengthfieldlength, int lengthadjustment, int initialbytestostrip. Maxframelength is the maximum length of the message. Lengthfieldoffset is the location of the header. Lengthfieldlength is the length of the header, Lengthadjustment is the length adjustment (the value in the default header indicates the length of the body.) Does not include the header itself), Initialbytestostrip is the number of bytes removed (the default decoding of all content returned header+body. This is set to 4 to remove the 4-byte header. Leaving only the body).


public class TCPServer {public static void main (string[] args) throws Interruptedexception {Eventloopgroup Bossgroup = new Nioeventloopgroup (); Eventloopgroup Workergroup = new Nioeventloopgroup (); try {serverbootstrap b = new Serverbootstrap (); B.group (BossGroup, Workergroup). Channel (Nioserversocketchannel.class). Childhandler (New channelinitializer<socketchannel> () {@ overridepublic void Initchannel (Socketchannel ch) throws Exception {Channelpipeline pipeline = Ch.pipeline ();// Lengthfieldbasedframedecoder cut messages by line, remove Bodypipeline.addlast (new Lengthfieldbasedframedecoder (80, 0, 4, 0, 4));// Then press UTF-8 encoding to turn to string pipeline.addlast (new Stringdecoder (charsetutil.utf_8));p ipeline.addlast (New Tcpserverhandler ());}); Channelfuture f = b.bind (8080). sync (); F.channel (). Closefuture (). sync (); finally {workergroup.shutdowngracefully (); bossgroup.shutdowngracefully ();}}} Class Tcpserverhandler extends Channelinboundhandleradapter {//Receive new data @overridepublic void Channelread ( Channelhandlercontext CTX, Object msg) {String message = (string) msg; System.out.println ("Channelread:" + message);} @Overridepublic void Channelactive (Channelhandlercontext ctx) {System.out.println ("channelactive");} @Overridepublic void Channelinactive (Channelhandlercontext ctx) {System.out.println ("channelinactive");} @Overridepublic void Exceptioncaught (Channelhandlercontext ctx, throwable cause) {cause.printstacktrace (); Ctx.close ( );}}

Twisted:

In twisted, you need to inherit int32stringreceiver, and no longer inherit protocol.

The int32stringreceiver represents a fixed 32-bit (4-byte) header, plus int16stringreceiver, int8stringreceiver, and so on. The method of accepting data events that need to be implemented is no longer datareceived, nor linereceived. But stringreceived.

#-*-coding:utf-8–*-from twisted.protocols.basic import int32stringreceiverfrom twisted.internet.protocol Import Factoryfrom twisted.internet Import Reactorclass tcpserverhandle (int32stringreceiver):    # New Connection Build    def Connectionmade (self):        print ' Connectionmade '    # Connection Disconnect    def connectionlost (self, Reason):        print ' Connectionlost '    # received new data    def stringreceived (self, data):        print ' stringreceived: ' + DataFactory = Factory ( ) Factory.protocol = tcpserverhandlereactor.listentcp (8080, Factory) Reactor.run ()

The following is a client test program written in Java:

public class TcpClient {public static void main (string[] args) throws IOException {socket socket = Null;dataoutputstream O UT = null;try {socket = new socket ("localhost", 8080), out = new DataOutputStream (Socket.getoutputstream ());//Request SERVERSTR ing data1 = "Newton"; byte[] outputBytes1 = data1.getbytes ("UTF-8"); Out.writeint (outputbytes1.length); Write Headerout.write (outputBytes1); Write bodystring data2 = "Einstein"; byte[] OutputBytes2 = data2.getbytes ("UTF-8"); Out.writeint (outputbytes2.length); Write Headerout.write (outputBytes2); Write Bodyout.flush ();} Finally {//close connection out.close (); Socket.close ();}}}


Minaserver Output Results:

sessioncreated
Messagereceived: Newton
Messagereceived: Einstein
Sessionclosed

Nettyserver Output Results:

Channelactive
Channelread: Newton
Channelread: Einstein
Channelinactive

Twisted Server Output results:

Connectionmade
Stringreceived: Newton
Stringreceived: Einstein
Connectionlost



Fork Brother reproduced please indicate the source: http://blog.csdn.net/xiao__gui/article/details/38752105



Copyright notice: This article Bo Master original articles, blogs, without consent may not be reproduced.

Mina, Netty, Twisted learn Together (iii): TCP prefix fixed-size message (Header)

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.