2011-10-29 34 views
14

Tôi có chương trình golang đơn giản sau để tải xuống chính sách bảo mật của Google. Thật không may, nó luôn luôn bị lỗi với lỗi unexpected EOF sau khi đọc 6861 byte, mặc dù tài liệu dài hơn nhiều. Tại sao?Đi: EOF bất ngờ khi đọc từ ổ cắm

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

kết quả đầu ra:

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

Trả lời

8

Chức năng io.ReadFull(fd, buf) nên được sử dụng chỉ khi bạn biết rằng fd thể ăn ít nhấtlen(buf) byte.

Thay vào đó, hãy thử như sau:

var buf bytes.Buffer 

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

Nếu sao chép vào một tập tin, sử dụng một os.File thay vì bytes.Buffer.

3

Tài liệu này không phải là lâu hơn nữa. Nó chỉ dài hơn 412 byte. Sine ReadFull không thể đọc tất cả 1024 byte, nó trả về unexpected EOF.

4

Bạn cũng có thể lấy kích thước của tệp từ tiêu đề HTTP và đọc đến độ dài đó trên ổ cắm của bạn. Tìm tiêu đề phản hồi Độ dài nội dung.

Bạn nên luôn luôn biết kích thước của những gì bạn đang di chuyển với IO, khi đó là một tệp và có thể, và giới hạn đọc của bạn với kích thước mong muốn. Điều này sẽ tránh được rất nhiều vấn đề. pseudocode:

$size = HTTP_RESPONSE['Content-Length']; 
while(reading to $size) 
{ 
    do something with chunk; 
} 
Các vấn đề liên quan