doumaogui5937
2014-06-21 08:06
采纳率: 100%
浏览 1.9k
已采纳

用Golang net.Conn.Read读取整个数据出错

我在Go中构建了一个网络应用程序,我看到Conn.Read读取一个有限的字节数组,这个数组是我用make([]字节,2048)创建的,现在的问题是我不知道内容的确切长度,所以它可能太多或者不够。

我的问题是,我如何才能读到确切的数据量?我想我得用bufio,但我不确定。能不能行得通。

图片转代码服务由CSDN问答提供 功能建议

因此,我在Go中构建了一个网络应用程序,并且看到了 Conn.Read 读入一个有限的字节数组,该数组是我用 make([] byte,2048)创建的,而现在的问题是我不知道确切的长度 内容,所以可能太多或不足。
我的问题是我如何才能读取准确的数据量。 我想我必须使用 bufio ,但不确定。

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • doubingjiu3199 2014-06-21 15:45
    已采纳

    It highly depends on what you're trying to do, and what kind of data you're expecting, for example if you just want to read until the EOF you could use something like this:

    func main() {
        conn, err := net.Dial("tcp", "google.com:80")
        if err != nil {
            fmt.Println("dial error:", err)
            return
        }
        defer conn.Close()
        fmt.Fprintf(conn, "GET / HTTP/1.0
    
    ")
    
        buf := make([]byte, 0, 4096) // big buffer
        tmp := make([]byte, 256)     // using small tmo buffer for demonstrating
        for {
            n, err := conn.Read(tmp)
            if err != nil {
                if err != io.EOF {
                    fmt.Println("read error:", err)
                }
                break
            }
            //fmt.Println("got", n, "bytes.")
            buf = append(buf, tmp[:n]...)
    
        }
        fmt.Println("total size:", len(buf))
        //fmt.Println(string(buf))
    }
    

    //edit: for completeness sake and @fabrizioM's great suggestion, which completely skipped my mind:

    func main() {
        conn, err := net.Dial("tcp", "google.com:80")
        if err != nil {
            fmt.Println("dial error:", err)
            return
        }
        defer conn.Close()
        fmt.Fprintf(conn, "GET / HTTP/1.0
    
    ")
        var buf bytes.Buffer
        io.Copy(&buf, conn)
        fmt.Println("total size:", buf.Len())
    }
    
    打赏 评论
  • doupapin172773 2014-06-21 11:20

    You can read data something like this:

    // import net/textproto
    import ("net/textproto", ...)
    
    ....
    
    reader := bufio.NewReader(Conn)
    tp := textproto.NewReader(reader)
    
    defer Conn.Close()
    
    for {
        // read one line (ended with 
     or 
    )
        line, _ := tp.ReadLine()
        // do something with data here, concat, handle and etc... 
    }
    ....
    
    打赏 评论
  • dth96108 2014-10-23 17:04

    You can use the ioutil.ReadAll function:

    import (
        "fmt"
        "io/ioutil"
        "net"
    )
    
    func whois(domain, server string) ([]byte, error) {
        conn, err := net.Dial("tcp", server+":43")
        if err != nil {
            return nil, err
        }
        defer conn.Close()
    
        fmt.Fprintf(conn, "%s
    ", domain)
        return ioutil.ReadAll(conn)
    }
    
    打赏 评论

相关推荐 更多相似问题