duanjing7298
2018-06-10 09:26
浏览 72
已采纳

Go中如何处理粘性TCP数据包?

I have a tcp server and a client, the server does the following

func providerCallback(conn net.Conn) {
    reader := bufio.NewReader(conn)
    var err error
    for {
        lenbyte, _ := reader.Peek(4)
        reader.Discard(4)
        slen := int(binary.BigEndian.Uint32(lenbyte))
        data, err = reader.Peek(slen)
        process(data)
        reader.Discard(slen)
    }
}

The client seems to send packet faster than process can deal with, therefore I'd like to buffer the requests in bufio and process later.

However, as the size of bufio is fixed(4096, even though I can increase it, it is still fixed), which means I can't manually Reset it because there might be a packet cutting of in the end of bufio, as follows

|normal data... [First 20 bytes of packet P] | [the rest of packet P]

|------------------- size of bufio ------------------|

How can I splice packet that is cut off, and reuse the bufio for later packets?

图片转代码服务由CSDN问答提供 功能建议

我有一个tcp服务器和一个客户端,该服务器执行以下操作

  func providerCallback(conn net.Conn){
 reader:= bufio.NewReader(conn)
 var err错误
 {
 lenbyte,_:= reader.Peek(4)
 reader。  Discard(4)
 slen:= int(binary.BigEndian.Uint32(lenbyte))
 data,err = reader.Peek(slen)
 process(data)
 reader.Discard(slen)
} \  n} 
   
 
 

客户端发送数据包的速度似乎超过了进程可以处理的速度,因此我想将请求缓存在bufio中,然后再处理。

但是,由于bufio的大小是固定的(4096,即使我可以增加它,它仍然是固定的),这意味着我不能手动 Reset ,因为 bufio的末尾可能会有一个数据包切割,如下所示

|普通数据... [数据包P的前20个字节] | [数据包P的其余部分]

| ------------------- bufio的大小--------- --------- |

我如何拼接被切断的数据包,并将bufio重新用于以后的数据包? \ n

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongxiang3205 2018-06-10 11:41
    已采纳

    For example,

    import (
        "bufio"
        "encoding/binary"
        "io"
        "net"
    )
    
    func providerCallback(conn net.Conn) error {
        rdr := bufio.NewReader(conn)
        data := make([]byte, 0, 4*1024)
        for {
            n, err := io.ReadFull(rdr, data[:4])
            data = data[:n]
            if err != nil {
                if err == io.EOF {
                    break
                }
                return err
            }
            dataLen := binary.BigEndian.Uint32(data)
            if uint64(dataLen) > uint64(cap(data)) {
                data = make([]byte, 0, dataLen)
            }
            n, err = io.ReadFull(rdr, data[:dataLen])
            data = data[:n]
            if err != nil {
                return err
            }
    
            process(data)
        }
        return nil
    }
    
    func process([]byte) {}
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题