title: can someone tell me what's the behavior of io.ReadFull and bytes.Buffer.ReadFrom in golang
body: <p>I have a problem when I implement a tcp c/s demo, I found it's weird when I use io.ReadFull(conn, aByteArr) or bytes.Buffer.ReadFrom(conn) on the server side, it seems that the server won't read the data in the connnection until the client quit, in other words, the server is stucked, but I can use the basic conn.Read(aBuffer) to read data. why the two methods are so strange? </p>
  
  <p>because I want my server to handle data of arbitrary size, so I don't like to use the basic way, I mean conn.Read(), which must make a bytes slice with specified size first. Please help me.</p>
  
  <p>i can give my code:
  client:</p>
  
  <pre><code>package main
  
  import (
      "net"
      "fmt"
      "bufio"
      "time"
      "runtime"
  )
  
  func send(s string, ch chan string){
      conn, err := net.Dial("tcp", ":4000")
      if err != nil {
          fmt.Println(err)
      }   
      fmt.Fprintf(conn, s)
      fmt.Println("send: ", s)                                                                                                                                                                                      
      /*  
      s := "server run"
      conn.Write([]byte(s))
      */
      status, err := bufio.NewReader(conn).ReadString('\n')
      if err != nil {
          fmt.Println("error: ", err)
      }   
      ch &lt;- status 
  }
  func main(){
      runtime.GOMAXPROCS(runtime.NumCPU())
      fmt.Println("cpu: ", runtime.NumCPU())
      ch := make(chan string, 5)
      timeout := time.After(10 * time.Second)
      i := 0
  
      for{
          go send(fmt.Sprintf("%s%d", "client", i), ch) 
          i++ 
          select {
              case ret := &lt;-ch:
                  fmt.Println(ret)
              case &lt;-timeout:
                  fmt.Println("time out")
                  return
          }   
      }   
  }
  </code></pre>
  
  <p>server:</p>
  
  <pre><code>package main
  
  import (
      "net"
      "log"
      "io"
      "fmt"
      "time"
      //"bytes"
  )
  
  func main(){
      // Listen on TCP port 2000 on all interfaces.
      l, err := net.Listen("tcp", ":4000")
      if err != nil {
          log.Fatal(err)
      }   
      defer l.Close()
      for {
          // Wait for a connection.
          conn, err := l.Accept()
          if err != nil {
              log.Fatal(err)
          }   
          // Handle the connection in a new goroutine.
          // The loop then returns to accepting, so that
          // multiple connections may be served concurrently.
          go func(c net.Conn) {
              fmt.Println(c.RemoteAddr())
              defer c.Close()
              // Echo all incoming data.
              /*  basic
              buf := make([]byte, 100)
              c.Read(buf)
              fmt.Println(string(buf))
              //io.Copy(c, c)
              c.Write(buf)
              // Shut down the connection.
              */
  
              /* use a ReadFrom
              var b bytes.Buffer                                                                                                                                                                                    
              b.ReadFrom(conn)
  
              fmt.Println("length: ", b.Len())
              c.Write(b.Bytes())
              */
  
              // use io.ReadAll
              byteArr := make([]byte, 100)
  
              n, err := io.ReadFull(c, byteArr)
              if err != nil {
                  fmt.Println(err)
              }   
              fmt.Println(n, byteArr[:n], time.Now())
              n, _ = c.Write(byteArr[:n])
              fmt.Println("write: ", n, time.Now())
          }(conn)
      }
  }   
  </code></pre>