首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高朗写到http响应中断输入读取?

高朗写到http响应中断输入读取?
EN

Stack Overflow用户
提问于 2015-02-05 04:36:38
回答 1查看 936关注 0票数 2

我正在尝试用Go编写一个小型的webapp,用户以多部分的形式上传一个gzipped文件。该应用程序解压缩和解析文件,并将一些输出写入响应。但是,当我开始写入响应时,我一直遇到一个错误,输入流看起来已损坏。不写入响应解决了问题,从非gzipped输入流进行读取也是如此。下面是一个示例http处理程序:

代码语言:javascript
复制
func(w http.ResponseWriter, req *http.Request) {

//Get an input stream from the multipart reader
//and read it using a scanner
multiReader, _ := req.MultipartReader()
part, _ := multiReader.NextPart()
gzipReader, _ := gzip.NewReader(part)
scanner := bufio.NewScanner(gzipReader)

//Strings read from the input stream go to this channel     
inputChan := make(chan string, 1000)

//Signal completion on this channel 
donechan := make(chan bool, 1)

//This goroutine just reads text from the input scanner
//and sends it into the channel 
go func() {
    for scanner.Scan() {
        inputChan <- scanner.Text()
    }       
    close(inputChan)
}()

//Read lines from input channel. They all either start with #
//or have ten tab-separated columns
go func() {
    for line := range inputChan {
        toks := strings.Split(line, "\t")
        if len(toks) != 10 && line[0] != '#' {
            panic("Dang.")
        }
    }
    donechan <- true 
}()

//periodically write some random text to the response
go func() {
    for {
        time.Sleep(10*time.Millisecond)     
        w.Write([]byte("write\n some \n output\n"))
    }
}()

//wait until we're done to return
<-donechan
}

奇怪的是,这段代码每次都会惊慌失措,因为它总是遇到少于10个标记的一行,尽管每次都在不同的地方。注释掉写入响应的行修复了问题,从非gzipped输入流进行读取也是如此。我漏掉了什么明显的东西吗?如果读取gzip文件而不是纯文本格式的文件,为什么写入响应会中断?它为什么会破裂呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-05 07:39:01

HTTP协议不是全双工的:它是基于请求响应的.您应该只在读取完输入后才发送输出。

在您的代码中,您在通道上使用forrange。这将尝试读取通道,直到它关闭,但您永远不会关闭inputChan

如果您从未关闭inputChan,则永远不会到达以下行:

代码语言:javascript
复制
donechan <- true 

因此,从donechan块接收:

代码语言:javascript
复制
<-donechan

当到达EOF时,您必须关闭inputChan

代码语言:javascript
复制
go func() {
    for scanner.Scan() {
        inputChan <- scanner.Text()
    }       
    close(inputChan) // THIS IS NEEDED
}()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28336313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档