drtpbx3606 2016-12-20 19:46
浏览 686
已采纳

golang中byte []通道的用法

I am new with golang channels and have a strange behavior I cannot explain. I am getting a REST command, and want to calculate hash function on it's body. To do so I read the body using io.TeeReader(request.Body, &writerToHash) where I pass my own class that implements io.Writer:

func (self *WriterToHash) Write(p []byte) (n int, err error) {
    n=len(p)
    fmt.println("WriterToHash  len=%v, buff=%v", n, p)  //PRINT 1
    self.BodyChannel <- p
    return n, nil
}

The BodyChannel is defined: BodyChannel chan []byte

I use this class as follows:

    writerToHash := sisutils.WriterToHash{
        BodyChannel:make(chan []byte, 1024)
    }
    writerToHash.StartListen()
    reqnew, _ := http.NewRequest("PUT", url, io.TeeReader(request.Body, &writerToHash))

Listening part:

func (wth *WriterToHash) StartListen() {
    wth.OutChannel = make(chan []byte, 1000)
    go func (self *WriterToHash) {
        done := int64(0)
        h := sha1.New()
        for done < MessageSize{
            buff := <- self.BodyChannel

            done += int64(len(buff))
            DPrint(5, "AccamulateSha1 Done=: %v, buff=%v", done, buff)  //PRINT 2

            actually_write, err := h.Write(buff)
            if err != nil ||  actually_write != len(buff) {
                log.Println("Error in sha write:" + err.Error())
                break
            }
        }
        bs := h.Sum(nil)
        self.OutChannel <- bs
    }(wth)
 }

I send messages of 1000 bytes. In debug mode the message is always split in the same way: 1 byte, 999 bytes - I see it using PRINT 1. In this case everythong works fine. The problem is that when the message is split to more parts in the Write function. In this case I see in PRINT1:

[first byte] : a

[next ~450 bytes] : b,c,d,...

[last ~550 bytes] : w,x,y,...

but in PRINT 2 I see different picture:

[first byte] : a

[ ~450 bytes but starting where last part starts] : w,x,y...

[last ~550 bytes] : w,x,y,...

I actually get the last past twice but not in the same size.

I have no idea why this is happening and will appreciate any help.

  • 写回答

1条回答 默认 最新

  • dongmeiwei0226 2016-12-20 20:05
    关注

    From the io.Writer documentation:

    Write must not modify the slice data, even temporarily. Implementations must not retain p

    You can't store or reuse the slice being passed to your Write method. If you want to use that data elsewhere, you need to make a copy of it

    func (self *WriterToHash) Write(p []byte) (n int, err error) {
        b := make([]byte, len(p))
        copy(b, p)
        fmt.println("WriterToHash  len=%d, buff=%v", len(p), b)
        self.BodyChannel <- b
        return len(p), nil
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮