1

我正在尝试通过 chan 将 []byte 提供给 gob 解码器。它可以工作,但起初解码器会抛出一大堆 EOF 错误然后停止。当它停止抛出错误时,程序的行为与我期望的完全一样,它会解码 gobs 并正确处理它产生的结构。

这是调用函数,正在读取的通道是 SSH 通道。

log.Println("Reading channel")
dchan := make(chan []byte, 200)
go decoder(dchan)
for {
    buf := make([]byte, 1024)
    //log.Println("Waiting for data")
    numBytes, err := channel.Read(buf)
    if err != nil {
        log.Println(err)
        continue
    }
    dchan <- buf[:numBytes]
}

解码器函数如下所示:

func decoder(dchan chan []byte) error {
  gob.Register(datums.Message{})
  var message datums.Message
  bbuf := bytes.NewBuffer(make([]byte, 512))
  dec := gob.NewDecoder(bbuf)
  for data := range dchan {
    //log.Println("Decoding data")
    bbuf.Write(data)
    err := dec.Decode(&message)
    if err != nil {
        log.Println("Error in decoder")
        log.Println(err)
        continue
    }
    //log.Println(&message)
  }
  return nil
}

我不确定这是否是一个真正的问题,gob 解码器是从缓冲区中删除数据还是将其保留在那里,直到出现足够的数据来生成值?

4

1 回答 1

1

调用channel.Read(buf)可以读取部分 gob。解码器在尝试解码部分 gob 时将返回错误。

因为通道满足io.Reader接口,所以应用程序可以直接在通道上创建解码器:

gob.Register(datums.Message{})
dec := gob.NewDecoder(channel)
for {
  var message datums.Message
  err := dec.Decode(&message)
  if err != nil {
     log.Println("Error in decoder", err)
     break
  }
  log.Println(&message)
}
于 2019-03-17T00:14:53.913 回答