《Go语言圣经》练习8.1 多个server对1个client
题目如下:
练习 8.1: 修改clock2来支持传入参数作为端口号
,然后写一个clockwall的程序,这个程序可以同时与多个clock服务器通信,从多个服务器中读取时间
,并且在一个表格中一次显示所有服务器传回的结果,类似于你在某些办公室里看到的时钟墙。
如果你有地理学上分布式的服务器可以用的话,让这些服务器跑在不同的机器上面;或者在同一台机器上跑多个不同的实例,这些实例监听不同的端口,假装自己在不同的时区。像下面这样:
下面表示开启单个服务器终端
$ TZ=US/Eastern ./clock2 -port 8010 &
$ TZ=Asia/Tokyo ./clock2 -port 8020 &
$ TZ=Europe/London ./clock2 -port 8030 &
$ clockwall NewYork=localhost:8010 Tokyo=localhost:8020 London=localhost:8030
解析:
直接写出来非常简单,主要key如下:
- client只需要对 处理来自server的函数 加上
go
变成goroutine即可。 - client获取命令行输入的port参数
- 命令行开启多个server
难点:
花了进2个小时才找到原因所在,每次运行了client 就直接退出。
主要原因是:主程序半天没有获取到来自server的输出,直接退出。(server有设置延迟等待)
因此,我们需要在client的main()函数在执行之前加入 flag.Parse()
等待获取参数
下面是代码:
clockwall.go
func main() {
flag.Parse() // 暂停获取参数!!!
for _, port := range os.Args[1:] {
//获取命令行输入 ./clockwall 8002 8003 8004
go dail(port) // 处理每个端口连接
}
for {
time.Sleep(5 * time.Second)
}
}
/*下面的不太是重点*/
func dail(port string) {
port_ := "localhost:" + port
fmt.Print(port_)
conn, err := net.Dial("tcp", port_)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
mustCopy(os.Stdout, conn)
}
func mustCopy(dst io.Writer, src io.Reader)