【发布时间】:2014-02-03 23:55:42
【问题描述】:
我在实现 tcp c/s 演示时遇到问题,我发现在服务器端使用 io.ReadFull(conn, aByteArr) 或 bytes.Buffer.ReadFrom(conn) 时很奇怪,似乎在客户端退出之前,服务器不会读取连接中的数据,换句话说,服务器卡住了,但我可以使用基本的 conn.Read(aBuffer) 来读取数据。为什么这两种方法如此奇怪?
因为我希望我的服务器处理任意大小的数据,所以我不喜欢使用基本的方式,我的意思是 conn.Read(),它必须首先制作一个指定大小的字节切片。请帮帮我。
我可以给出我的代码: 客户:
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 <- 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
}
}
}
服务器:
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)
}
}
【问题讨论】: