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?
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.
i can give my code: client:
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('
')
if err != nil {
fmt.Println("error: ", err)
}
ch <- 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 := <-ch:
fmt.Println(ret)
case <-timeout:
fmt.Println("time out")
return
}
}
}
server:
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)
}
}