Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read whole data with Golang net.Conn.Read

Tags:

go

So I'm building a network app in Go and I've seen that Conn.Read reads into a limited byte array, which I had created with make([]byte, 2048) and now the problem is that I don't know the exact length of the content, so it could be too much or not enough.
My question is how can I just read the exact amount of data. I think I have to use bufio, but I'm not sure.

like image 500
user2563892 Avatar asked Jun 21 '14 08:06

user2563892


2 Answers

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\r\n\r\n")      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\r\n\r\n")     var buf bytes.Buffer     io.Copy(&buf, conn)     fmt.Println("total size:", buf.Len()) } 
like image 76
OneOfOne Avatar answered Oct 01 '22 04:10

OneOfOne


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\r\n", domain)     return ioutil.ReadAll(conn) } 
like image 22
vially Avatar answered Oct 01 '22 06:10

vially