Go:高效处理通过TCP接收的碎片数据

Go:高效处理通过TCP接收的碎片数据,tcp,go,buffer,Tcp,Go,Buffer,我正在编写一个小型tcp服务器,它只负责读取数据、解析接收数据(动态长度帧)并处理这些帧。考虑下面的代码: func ClientHandler(conn net.Conn) { buf := make([]byte, 4096) n, err := conn.Read(buf) if err != nil { fmt.Println("Error reading:", err.Error()) return } fmt.P

我正在编写一个小型tcp服务器,它只负责读取数据、解析接收数据(动态长度帧)并处理这些帧。考虑下面的代码:

func ClientHandler(conn net.Conn) {
    buf := make([]byte, 4096)
    n, err := conn.Read(buf)
    if err != nil {
        fmt.Println("Error reading:", err.Error())
        return
    }
    fmt.Println("received ", n, " bytes of data =", string(buf))
    handleData(buf)
这就是我的代码的本质。我将X字节读入一个空缓冲区,然后处理数据

问题发生在以下情况:

  • 数据帧大于它试图从tcp连接读入的缓冲区。在这种情况下,在接收到其余数据之前,我无法处理数据(但是接收缓冲区已经被以前的数据占用)
  • 当缓冲区包含一个半帧的数据时,我需要处理第一帧,同时保留不完整的帧供以后使用。。。在这种情况下,我需要从缓冲区中移除已处理的部分,并移动未完成的部分,以便为帧的其余部分留出空间
  • 这两种情况都可能需要重新分配和复制数据,这可能是一项成本高昂的操作?此外,除了扩展缓冲区之外,我不知道如何处理比缓冲区大的帧。。。但是,不断增加的缓冲区可能会导致性能问题和拒绝服务。最后,但并非最不重要的一点是,我对Golang的标准库不太了解,不知道是否有专门为处理这些情况而构建的包

    因此,我的问题是:

  • 是否有处理这些情况的最佳实践
  • 是否有任何golang软件包可以为我完成部分或大部分工作

  • 谢谢。

    字节片应该支持非常优化的大小调整(即保留比需要更多的字节,如果可以的话不复制,以指数形式增长,复制代码不是用go编写的,而是运行时的一部分,等等)

    因此,您可以使用
    append
    查看它的工作原理

    另一种更惯用的方法是使用
    bufio.Reader
    包装连接,它将自动处理所有这些。我在自己编写的tcp服务器中使用过它,速度非常快。你只要做:

    r := bufio.NewReader(conn)
    

    然后你可以一直读到一个定界符,如果你事先知道的话,也可以读到给定的字节数

    实际上,我可以使用bufio中的ReadByte和ReadRune。谢谢