2011-10-29 6 views
14

Mam następujący prosty program golang, aby pobrać politykę prywatności Google. Niestety, zawsze zawiesza się z powodu błędu unexpected EOF po przeczytaniu 6861 bajtów, mimo że dokument jest znacznie dłuższy. Czemu?Go: nieoczekiwany EOF podczas odczytu z gniazda

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

wyjścia:

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

Odpowiedz

8

Funkcja io.ReadFull(fd, buf) powinny być stosowane tylko wtedy, gdy wiesz że fd można karmić przynajmniejlen(buf) bajtów.

Zamiast tego, spróbuj wykonać następujące czynności:

var buf bytes.Buffer 

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

Jeśli kopiowanie do pliku, należy użyć os.File zamiast bytes.Buffer.

3

Dokument nie jest znacznie dłuższa. To tylko 412 bajtów dłużej. Sine ReadFull nie może odczytać wszystkich 1024 bajtów, które zwróci unexpected EOF.

4

Możesz także pobrać rozmiar pliku z nagłówków HTTP i odczytać tę długość na swoim gnieździe. Poszukaj nagłówka odpowiedzi Content-Length.

Powinieneś zawsze wiedzieć, jaki ruch wykonujesz za pomocą IO, kiedy jest to plik i możliwe, i ograniczyć czytanie do oczekiwanego rozmiaru. Pozwoli to uniknąć wielu problemów. pseudokod:

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