2011-10-29 74 views
14

次のGoogleのプライバシーポリシーをダウンロードする簡単なgolangプログラムがあります。残念ながら、文書がかなり長くても、常に6861バイトを読み取った後にエラーunexpected EOFでクラッシュします。どうして?Go:予期しないソケットからの読み取り中の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)を使用する必要があります。

代わりに、次のことを試してください。

var buf bytes.Buffer 

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

ファイルにコピーする場合は、代わりにbytes.Bufferos.Fileを使用しています。

3

文書がはるかに長いではありません。それは412バイトだけです。 Sine ReadFullは1024バイトをすべて読み取ることができません。それはunexpected EOFを返します。あなたは少なくともlen(buf)バイトを養うことができfdことを知っているた場合にのみ

4

また、HTTPヘッダーからファイルのサイズを取得し、その長さのソケットを読み取ることもできます。 Content-Lengthレスポンスヘッダーを探します。

IOで移動しているファイルのサイズを知っている必要があります。ファイルであり、読み込み可能なサイズに制限されています。これにより、多くの問題を回避できます。 擬似コード:

$size = HTTP_RESPONSE['Content-Length']; 
while(reading to $size) 
{ 
    do something with chunk; 
} 
関連する問題