drdyszuy488152 2014-03-06 08:22
浏览 41
已采纳

继续:有效处理通过TCP接收的碎片数据

I am writing a small tcp-server that is only suppose to read data, parse the receiving data (dynamic length frames) and handling these frames. Consider the following code:

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)

This is pretty much the essence of my code as is. I read X bytes into a empty buffer and then handle the data.

The problem occurs when:

  1. a frame of data is bigger than the buffer it is trying to read into from the tcp connection. In this case I cannot handle the data until I receive the rest (but then the receving buffer is already occupied by the previous data).
  2. when the buffer contains one and a half frame of data and I need to handle the first frame, while keeping the incomplete frame for later... in this case I need to remove the handled part from the buffer, and move the incomplete part so that there is room for the remainder of the frame.

Both scenarios would probably require reallocation and copying of data, which may perhaps be a costly operation? Furthermore, I have no ideas on how to handle frames that are larger than the buffer except for expanding the buffer... but an ever-increasing buffer may perhaps lead to performance issues and denial of service. Last, but not least, I do not know the standard library of Golang good enough to know if there are any package built explicitly for handling these situations.

So my questions are:

  1. is there any best practice for handling these situations?
  2. is there any golang package that will do some or most of this for me?

Thank you.

  • 写回答

1条回答 默认 最新

  • dongying2112 2014-03-06 09:56
    关注

    byte slices should support pretty optimized resizing (i.e. reserving more bytes than needed, not copying if they can, growing exponentially, the copying code is not written in go but part of the runtime, etc).

    so you can use append and see how it works.

    Another, more idiomatic approach, is using bufio.Reader to wrap the connection, and it will handle all this automatically. I've used it in a tcp server I've written and it was extremely fast. You just do:

    r := bufio.NewReader(conn)
    

    and then you can either read until a delimiter or a given amount of bytes if you know it in advance.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题
  • ¥15 lna设计 源简并电感型共源放大器