Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get an io.ByteReader from a net.Conn

Tags:

go

I am connecting to a TCP/IP server using Go code similar to:

conn, err := net.Dial("tcp", host+":"+strconv.Itoa(port))

Now I need to use binary.ReadVariant which takes an io.ByteReader, so trying to write code like this:

var length int64
var err error
length, err = binary.ReadVarint(conn)

Gives me an error like:

./main.go:67: cannot use conn (type net.Conn) as type io.ByteReader in function argument:
    net.Conn does not implement io.ByteReader (missing ReadByte method)

How can I make this work?

like image 621
maxpenguin Avatar asked Feb 08 '14 06:02

maxpenguin


2 Answers

The problem is that the underlying net.TCPConn returned by net.Dial as net.Conn only implements the Read(byte[]) (int, err) method. This means that the returned net.Conn satisfies the io.Reader interface, but it does not satisfy the io.ByteReader interface because net.TCPConn doesn't have a ReadByte() (c byte, err error) method.

You can use the bufio.NewReader function to wrap the net.Conn in a type that does implement the io.ByteReader interface.

Example:

package main

import (
    "bufio"
    "encoding/binary"
    "fmt"
    "net"
)

func main() {
    conn, err := net.Dial("tcp", "google.com:80")
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")

    length, err := binary.ReadVarint(bufio.NewReader(conn))
    if err != nil {
    panic(err)
    }
    fmt.Println(length)
}
like image 194
mortdeus Avatar answered Oct 22 '22 18:10

mortdeus


bufio.Reader implements the ByteReader interface.

Wrapping conn using bufio.NewReader(conn) should work.

like image 25
Chandra Sekar Avatar answered Oct 22 '22 19:10

Chandra Sekar