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
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 lammps拉伸应力应变曲线分析
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题
  • ¥30 python代码,帮调试,帮帮忙吧
  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建