2016-12-20 6 views
2

나는 golang 채널을 처음 사용하며 설명 할 수없는 이상한 동작이 있습니다. REST 명령을 받고 있는데 해시 함수를 계산하려고합니다. 다음과 같이 내가이 클래스를 사용 BodyChannel chan []bytegolang의 [] 채널 사용량

:

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 
} 

BodyChannel가 정의 : 내가 io.Writer를 구현하는 내 자신의 클래스를 통과 io.TeeReader(request.Body, &writerToHash)를 사용하여 몸을 읽을 이렇게하려면

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

듣기 부분 :

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) 
} 

나는 1000 바이트의 메시지를 보낸다. 디버그 모드에서 메시지는 항상 같은 방식으로 분할됩니다 : 1 바이트, 999 바이트 - 인쇄 1을 사용하여 볼 수 있습니다.이 경우 everythong 제대로 작동합니다. 문제는 메시지가 쓰기 기능의 다른 부분으로 분할 될 때입니다. 이때 I는 PRINT1에 참조 :

[첫번째 바이트]하십시오

[다음 ~ 450 바이트] B, C, D ...

[마지막 ~ 550 바이트] w [마지막 부분이 시작하는 위치 ~ 450 바이트이지만 시작]을

:

[첫번째 바이트], X, Y는, ...

하지만

는 PRINT 2 I 다른 픽처를 참조 w, X , y ...

[마지막 ~ 550 바이트] : w, x, y, ...

실제로 지난번 두 번 있지만 동일한 크기가 아닙니다.

왜 이런 일이 발생하는지 알지 못하며 어떤 도움을 주셔서 감사합니다. io.Writer documentation에서

답변

3

:

쓰기도 일시적으로 슬라이스 데이터를 수정하지 않아야합니다. 구현시 p를 유지하면 안됩니다.

Write 메서드로 전달되는 슬라이스를 저장하거나 다시 사용할 수 없습니다. 해당 데이터를 다른 곳에서 사용하려면 사본을 만들어야합니다.

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 
} 
+0

짐 감사합니다. 그런데 왜 스트림이 항상 첫 번째 바이트 + 나머지로 나뉘 었는지 알 수 있습니까? – Ety

+0

@Ety : TeeReader는 독자가 읽은 것을 정확하게 씁니다. 따라서 'request.Body'에서 한 바이트가 읽혀지면 한 바이트가'writerToHash'에 기록됩니다. 작은 읽기 쓰기 작업이 문제가 될 경우 (귀하의 경우 중요하지 않음), bufio를 사용하여 더 큰 작업으로 일괄 처리하십시오. – JimB