需求

修改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

实现

  • go语言tcp
  • 并发编程
  • waitgroup

服务端

package main  

import (
"flag"
"fmt" "io" "net" "os" "time")

func main() {
var port string
flag.StringVar(&port, "port", "9999", "监听端口")
flag.Parse()
if err := handlerListen(port); err != nil {
fmt.Println(err)
}
}

func handlerListen(port string) error {
// 建立链接
listener, err := net.Listen("tcp", port)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer listener.Close()

for {
conn, err := listener.Accept()
if err != nil {
fmt.Println(err)
os.Exit(1)
}

go func(conn net.Conn) {
defer conn.Close()
io.WriteString(conn, time.Now().Format("2006-01-02 15:04:05"))
}(conn)

}
return nil
}

客户端

package main  

import (
"fmt"
"io" "net" "os" "strings" "sync")

func main() {
wg := sync.WaitGroup{}
for _, arg := range os.Args[1:] {
line := strings.Split(arg, "=")
name, addr := line[0], line[1]

wg.Add(1)
go myHandle(name, addr, &wg)
}
wg.Wait()
}

func myHandle(name, addr string, wg *sync.WaitGroup) {
defer wg.Done()
// 创建tcp链接
conn, err := net.Dial("tcp", addr)
if err != nil {
fmt.Printf("Error connecting to server: %s\n", err)
}

defer conn.Close()
buf := make([]byte, 1024)
_, err = conn.Read(buf)
if err != nil {
fmt.Printf("Error reading from server: %s\n", err)
}
io.WriteString(os.Stdout, name+":"+string(buf[:])+"\n")
}