关于golang:go语言下tcp粘包分包的简单处理

14次阅读

共计 1168 个字符,预计需要花费 3 分钟才能阅读完成。

go 在网络编程中真的很香

什么是粘包分包:

集体了解,TCP 的流式传输会因为网络情况而导致接收端每次收到的数据和发送端每次发送的数据略有差异 
e.g.  发送时为 {123} {456} 承受时为 {12} {3456}


办法 1:应用 websocket,无需解决
办法 2:失常 tcp 流程下应用长度法:
利用 time.Sleep(time.Nanosecond)来重现网络卡顿状况,复现粘包
服务端

func main(){listen , _ := net.Listen("tcp", "127.0.0.1:8888")
    fmt.Println("start listen")
    for {conn, err := listen.Accept()
        if err!=nil {continue}
        go process(conn)
    }
}
func process(conn net.Conn) {fmt.Printf("new conn %d", conn.RemoteAddr())
    // var buffer = make([]byte, 100)

    for {reader := bufio.NewReader(conn)
        peek, _ := reader.Peek(4)
        buffer := bytes.NewBuffer(peek)
        var length int32
        binary.Read(buffer, binary.BigEndian, &length)

        if int32(reader.Buffered()) < length+4 {continue}
        data := make([]byte, length+4)
        _, err := reader.Read(data)
        if err!=nil {continue}
        fmt.Println(string(data[4:]))

    }
}

客户端

func main() {conn, err:=     net.Dial("tcp", "127.0.0.1:8888")
    if err!=nil {fmt.Println(err)
        return
    }
    for i := 0; i < 100; i++{data, _ := Encode(time.Now().String())
        conn.Write(data)
        // time.Sleep(1*time.Second)

    }
}
func Encode(message string) ([]byte, error) {var length = int32(len(message))
    var pkg = new(bytes.Buffer)

    err := binary.Write(pkg, binary.BigEndian, length)
    if err!=nil {return nil, err}
    err = binary.Write(pkg, binary.BigEndian, []byte(message))
    if err!=nil {return nil, err}
    return pkg.Bytes(), nil}

正文完
 0