一个简单的多协程并发服务器,客户端从标准输入读取内容,服务器处理后返回。
专栏的介绍可以参考 《CaseGolang专栏》,代码可以看《宝库-Case》。
案例比较简单:客户端从标准输入读取内容发送给服务器,服务器处理之后返回给客户端。
(中间关于读写的时候,有些小细节要注意;不展开直接看代码吧)
直接贴代码:(server.go)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| package main
import ( "io" "strings" "fmt" "log" "net" )
func main() { listener, err := net.Listen("tcp", "127.0.0.1:8000") if err != nil { log.Fatalln("err = ", err) } defer listener.Close()
for { conn, err := listener.Accept() if err != nil { log.Fatalln("err = ", err) } go HandleConn(conn) } }
func HandleConn(conn net.Conn) { defer conn.Close()
addr := conn.RemoteAddr().String() fmt.Println(addr + "addr connect succeed")
buf := make([]byte, 1024*4)
for { n, err := conn.Read(buf) if err != nil { if err != io.EOF { fmt.Println("err = ", err) } return } fmt.Println("read buf = ", string(buf[:n]))
conn.Write([]byte(strings.ToUpper(string(buf[:n])))) }
}
|
然后 client.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| package main
import ( "os" "fmt" "net" )
func main() { conn, err := net.Dial("tcp", "127.0.0.1:8000") if err != nil { fmt.Println("dial err : ", err) return } defer conn.Close()
go func() { str := make([]byte, 1024) for { n, err := os.Stdin.Read(str) if err != nil { fmt.Println("os.Stdin, err = ", err) return }
conn.Write(str[:n]) }
}()
buf := make([]byte, 1024) for { n, err := conn.Read(buf) if err != nil { fmt.Println("read err = ", err) return } fmt.Println(string(buf[:n])) } }
|
不解释了,注意下 IO 的处理,还有一种方式,判断读取的字节数 n 。
运行大致如下:
Merlin 网络小案例 upload