GO Manual Processing of TCP Packets

Application Scenarios

Use custom communication protocol in most TCP communication scenarios

image.png

Sticky Packet Processing Principle: Buffer data sent by clients N times into a single packet by the size of the packet in the request header
For example:
Request header takes up 3 bytes (instruction header 1 byte, packet length 2 bytes), version takes up 1 byte, instruction takes up 2 bytes
The protocol specifies a maximum of 512 bytes for a packet, 1300 bytes for a packet record in the request header, and 1307 bytes for a complete packet. At this time, the server needs to glue the data sent by the client three times.

Code Samples

package server

import (
    "net"
    "bufio"
    "ftj-data-synchro/protocol"
    "golang.org/x/text/transform"
    "golang.org/x/text/encoding/simplifiedchinese"
    "io/ioutil"
    "bytes"
    "ftj-data-synchro/logic"
    "fmt"
    "strconv"
)

/*
 Client Architecture
 */
type Client struct {
    DeviceID string        //Flag-only for client connections
    Conn     net.Conn      //Connect
    reader   *bufio.Reader //read
    writer   *bufio.Writer //output
    Data     []byte        //receive data
}

func NewClient(conn *net.TCPConn) *Client {
    reader := bufio.NewReaderSize(conn, 10240)
    writer := bufio.NewWriter(conn)
    c := &Client{Conn:conn, reader:reader, writer:writer}
    return c

}

/**
    Data Read (Glue Pack Processing)
 */
func (this *Client)read() {
    for {
        var data []byte
        var err error
        //The read command header returns the first four bytes of the input stream without moving the read position
        data, err = this.reader.Peek(4)
        if len(data) == 0 || err != nil {
            continue
        }
        //Returns the number of bytes available for reading in the buffer
        var byteSize = this.reader.Buffered()
        fmt.Printf("Read byte length:%d\n", byteSize)
        //Generate a byte array of readable bytes in the buffer
        data = make([]byte, byteSize)
        //Read data in buffer
        this.reader.Read(data)
        fmt.Printf("Read bytes:%d\n", data)
        //Save to a new buffer
        for _, v := range data {
            this.Data = append(this.Data, v)
        }

        if len(this.Data) < 4 {
            //Packet Buffer Empty
            this.Data = []byte{}
            fmt.Printf("Illegal data, no header...\n")
            continue
        }

        data, err = protocol.HexBytesToBytes(this.Data[:4])
        instructHead, _ := strconv.ParseUint(string(data), 16, 16)
        //Instruction Header Validity
        if uint16(instructHead) != 42330 {
            fmt.Printf("invalid data\n")
            //Packet Buffer Empty
            this.Data = []byte{}
            continue
        }

        data = this.Data[:protocol.HEADER_SIZE]

        var p = protocol.Decode(data)
        fmt.Printf("Message body length:%d\n", p.Len)

        var bodyLength = len(this.Data)
        
      /**
            Determine if the size of the packet buffer is smaller than the size of the packet in the protocol request header
            If less than, wait for the next client packet to be read, otherwise decode the packet for business logic processing
         */
        if int(p.Len) > len(this.Data) - protocol.HEADER_SIZE {
            fmt.Printf("body Body length:%d,Read body Body length:%d\n", p.Len, bodyLength)
            continue
        }
        fmt.Printf("Actual processing bytes:%v\n", this.Data)
        p = protocol.Decode(this.Data)
        //Logical Processing
        go this.logicHandler(p)
        //Packet Buffer Empty
        this.Data = []byte{}
    }
}

The section to be optimized:

type Client struct {
    DeviceID string        //Flag-only for client connections
    Conn     net.Conn      //Connect
    reader   *bufio.Reader //read
    writer   *bufio.Writer //output
    Data     []byte        //receive data
}

The Data attribute in the structure can be considered for useBytes.BufferRealization.

Golang Standard Library Documentation:https://studygolang.com/pkgdoc

The above is an original article, please indicate the author @Curry
QQ:208275451

Keywords: encoding less Attribute

Added by kellerkind on Fri, 26 Jun 2020 19:08:50 +0300