2011-10-29 15 views
14

Tengo el siguiente programa simple de golang para descargar la política de privacidad de Google. Lamentablemente, siempre se bloquea con el error unexpected EOF después de leer 6861 bytes, aunque el documento es mucho más largo. ¿Por qué?Ir: EOF inesperado al leer de un socket

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

salidas:

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

Respuesta

8

Función io.ReadFull(fd, buf) se debe utilizar sólo cuando se sabe que fd puede alimentar al menoslen(buf) bytes.

En su lugar, pruebe lo siguiente:

var buf bytes.Buffer 

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

Si la copia de un archivo, utilice un os.File en lugar de bytes.Buffer.

3

El documento no es mucho más largo. Solo tiene 412 bytes más. Sine ReadFull no puede leer todos los 1024 bytes devuelve unexpected EOF.

4

También puede obtener el tamaño del archivo de los encabezados HTTP y leer hasta esa longitud en su socket. Busque el encabezado de respuesta de longitud de contenido.

Siempre debe saber el tamaño de lo que se está moviendo con IO, cuando es un archivo y es posible, y limitar su lectura al tamaño esperado. Esto evitará muchos problemas. pseudocódigo:

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