2011-10-29 40 views
14

我有以下简单的golang程序来下载Google的隐私政策。不幸的是,即使文档长得多,在读取6861个字节后,它总是与错误unexpected EOF一起崩溃。为什么?前往:意外的EOF,同时从插座读取

package main 

import "net" 
import "fmt" 
import "io" 
import "os" 

func die(msg string, s os.Error) { 
    fmt.Printf("%s crashed: %v\n", msg, s) 
    os.Exit(1) 
} 

func main() { 
    fd, err := net.Dial("tcp", "google.com:80") 
    if err != nil { die("dial", err) } 

    req := []byte("GET /intl/en/privacy/ HTTP/1.0\r\nHost: www.google.com\r\n\r\n") 
    _, err = fd.Write(req) 
    if err != nil { die("dial write", err) } 

    buf := make([]byte, 1024) 
    nr := 1 

    for nr > 0 { 
     nr, err = io.ReadFull(fd, buf) 
     if err != nil { die("dial read", err) } 
     fmt.Printf("read %d\n", nr) 
    } 
} 

输出:

read 1024 
read 1024 
read 1024 
read 1024 
read 1024 
read 1024 
dial read crashed: unexpected EOF 

回答

8

功能io.ReadFull(fd, buf)应使用只有当你知道fd可以养活至少len(buf)字节。

相反,请尝试以下操作:

var buf bytes.Buffer 

nr, err := io.Copy(&buf, fd) 
if err != nil { 
    die("dial read", err) 
} 

如果复制到一个文件中,使用os.File代替bytes.Buffer

3

该文件是不是要长得多。它只有412个字节长。 Sine ReadFull无法读取全部1024字节,它将返回unexpected EOF

4

您还可以从HTTP标头获取文件的大小,并在套接字上读取该长度。查找内容长度响应标题。

您应该始终知道IO移动的大小,当它是文件并且可能时,并将读取限制为预期的大小。这将避免很多问题。 伪代码:

$size = HTTP_RESPONSE['Content-Length']; 
while(reading to $size) 
{ 
    do something with chunk; 
}