BYTE serialization operations in Golang

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

When writing a network program, we often need to serialize data types such as structs or integers into a binary buffer string. or from a buffer to parse out a struct, the most typical is in the header part of the protocol to characterize head length or body length in the process of package and unpacking, need to follow the specified integer type parsing, and involves the problem of the size of the end sequence.

How does it work in the 1.C?

Our simplest approach in C is to use memcpy to copy other types, such as an integer or struct, into a piece of memory, and then revert to the desired type in a strong way. Such as:

Listen to listen to produce listen int listen to listen to a listen = listen to 32; listen to the char listen to *buf listen = listen to (char Listen *) malloc (sizeof (int)); Listen and listen to the memcpy (buf,&a,sizeof (int)); Listen/listen to consume listen to int listen to B listen to listen to hear memcpy (&b,buf,sizeof (int))

When necessary, the Ntoh/hton series functions are used to convert the size of the end sequence.

Operation in 2.golang

The use of "encoding/binary" provides functionality for commonly used binary serialization. The module mainly provides several interfaces as follows:

func listen to read (R listen io. Reader, listen to order listen to Byteorder, listen to data listen interface{}) listen to Errorfunc listen write (w listen io. Writer, listen to order listen to Byteorder, listen to data listen interface{}) listen to Errorfunc listen to size (v listen interface{}) Listen to Intvar listen to Bigendian listen to Bigendianvar listen to Littleendian listen to Littleendian/*type listen to Byteorder listen to interface hear {Uint16 (]byte) Listen to Uint16uint32 ([]byte) listen to Uint32uint64 ([]byte) listen to uint64putuint16 ([]byte, Listen uint16) PutUint32 ([]byte, Listen UInt32) PutUint64 ([ ]byte, listen UInt64) String () Listen string}/* 

Through the read interface, you can populate the contents of the BUF into the data structure represented by the database parameter, and the Write interface allows you to write the data contained within the parameters to buffer. The variables Bigendian and Littleendian are objects that implement the Byteorder interface, which can be serialized (Uintx ()) or deserialized (Putuintx ()) to buf directly through the methods provided in the interface.

2.1 Serializing a struct to a buf

When serializing a struct object, it is important to note that the size of the serialized structure must be known, and that the size of the structure can be obtained through a size interface to determine the size of the buffer.

I listen: = Listen to UInt16 (1) Size listen: = listen to binary. Size (i)

A fixed-size structure requires that a member of a tile such as []byte] cannot appear in the struct, otherwise size returns-1 and cannot perform a normal serialization operation.

Type listen a listen to the struct listen {listen to listen//listen to should listen to listen to exported listen to member listen to listen to listen to listen to the "listen to" hear the one listen to hear the one hear the listen to the "Listen" var listen aa.one Listen = Listen to Int32 (1) A.two listen = Listen to Int32 (2) buf listen: = Listen to New (bytes. Buffer) fmt. Println ("A ' s listen to size listen is listen", binary.) Size (a)) binary. Write (buf,binary. Littleendian,a) fmt. Println ("After listening to write listen, buf listen is:", buf. Bytes ())

The corresponding output is:

A ' s listen to the size listen to is listen to 8after listen to write listen, buf listen to IS listen: listen to [1 listen to 0 listen to 0 listen to 0 Listen 2 Listen 0 listen to 0 listen to 0]

The size of the desired buffer can be obtained by size. Write allows you to serialize the contents of object a into buffer. This is done in a small-endian manner (the x86 architecture is small-endian, and the network byte-order is the big-end sequence).

The "_" member in the struct is not serialized.

2.2 Deserializing back a structure from BUF

When reading from buffer, the size of the struct is required to be fixed, and the members of the struct that need to be deserialized must be exportable, which must be the beginning of the uppercase, and also not deserialized for "_":

Type listen a listen to the struct listen {listen to listen//listen to should listen to listen to exported listen to member listen to listen to listen to listen to the "listen to" hear the one listen to hear the one hear the listen to the "Listen" var listen aa Listen abuf listen: = Listen to New (bytes. Buffer) binary. Write (buf,binary. littleendian,a) binary. Read (buf,binary. LITTLEENDIAN,&AA) fmt. Println ("After listening AA listen to is listening", aa)

The output is:

After listening to write listen, Bufis listen to: Listen to [1 listen to 0 listen to 0 listen to 0 listen to 2 listen to 0 listen to 0 listen to 0]before listen AA listen to IS listen to: Listen to {0 listen to the AA listen to is listen {1 listen to 2}

Here, use read to import the data into the struct object AA from buffer. If the corresponding member in the struct is not exportable, an error will be panic at the time of conversion.

2.3 Serializing integers to buf and deserializing them from BUF

We can use Read/write to read or write a variable of the Uintx type to realize the serialization and deserialization of the shaping number. Since the serialization of the shaping number is very common in the network, the system library provides the type Byteorder interface to facilitate the serialization and deserialization of Uint16/uint32/uint64:

Int16buf Listen: = Listen to New (bytes. Buffer) I listen: = Listen to UInt16 (1) binary. Write (int16buf,binary. Littleendian,i) fmt. Println ("Write Listen buf Listen is:" Int16buf. Bytes () var listen int16buf2 listen to [2]bytebinary. Littleendian.putuint16 (int16buf2[:],uint16 (1)) fmt. Println ("Put listen buffer listen to IS listen:", int16buf2[:]) II Listen: = listen to binary. Littleendian.uint16 (int16buf2[:]) fmt. Println ("Get listen buf listen to IS listen:", ii)

The output is:

Write hear buffer listen to IS listen: listen to [1 listen to 0]put listen to BUF listen is: Listen [1 listen to 0]get listen to buf listen to IS listen: listen to 1

by calling Binary. Littleendian.putuint16, the data of the UInt16 type can be serialized into buffer in the form of a small end order. Through binary. The littleendian.uint16 deserializes the contents of the buffer.

3. An example of a reality

Let's take a look at the definition and initialization of a network packet header:

Type listen to the head listen to the struct listen { Listen to listen to the cmd listen to listen to a byte listen to hear the uint16 listen to listen to the magic listen to hear the listening to listen to hear the Listen BUF []byte] *head{listen to the head listen: Listen to New (head) listen to listen to the head. CMD Listen listen = Listen buf[0 listen to listen to the head. Version listen = Listen Buf[1] Listen and listen to the head. Magic Listen listen = listen to binary. Bigendian.uint16 (Buf[2:4]) listen and listen to the head. Reserve Listen = listen to buf[4] listen and listen to the head. Headlen Listen = listen to buf[5] listen and listen to the head. Bodylen Listen = listen to binary. Bigendian.uint16 (Buf[6:8]) listen and hear return hear head}

This is a common example of a packet in TCP. In the example, binary is passed. Bigendian.uint16 reads the data in the form of a network order and puts it into the corresponding structure within the head.


This article is from the "done_in_72_hours" blog, so be sure to keep this source http://gotaly.blog.51cto.com/8861157/1539119

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.