2011-10-29 15 views
14

Ho il seguente semplice programma golang per scaricare la politica sulla privacy di Google. Sfortunatamente si blocca sempre con l'errore unexpected EOF dopo aver letto 6861 byte, anche se il documento è molto più lungo. Perché?Vai: EOF inatteso durante la lettura da una presa

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

uscite:

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

risposta

8

Funzione io.ReadFull(fd, buf) deve essere utilizzato solo quando si sa che fd può alimentare almenolen(buf) byte.

Invece, provare quanto segue:

var buf bytes.Buffer 

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

Se la copia di un file, utilizzare un os.File invece di bytes.Buffer.

3

Il documento non è molto più lungo. Sono solo 412 byte più lunghi. Sine ReadFull non può leggere tutti i 1024 byte restituisce unexpected EOF.

4

È anche possibile ottenere la dimensione del file dalle intestazioni HTTP e leggere su quella lunghezza sul socket. Cerca l'intestazione di risposta Content-Length.

Si dovrebbe sempre conoscere la dimensione di ciò che si sta spostando con IO, quando è un file e possibile e limitare la lettura alle dimensioni previste. Questo eviterà un sacco di problemi. pseudocodice:

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