1. 程式人生 > >[日常] Go語言聖經--示例: 並發的Clock服務習題

[日常] Go語言聖經--示例: 並發的Clock服務習題

time 入參 tco local nec 聖經 int conn read

練習 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

clock2.go

package main

import (
        "flag"
        "io"
        "log"
        "net"
        "time"
)

//支持傳入參數作為端口號
var port = flag.String("port", "8000", "請輸入端口")

func main() {
        flag.Parse()
        listener, err := net.Listen("tcp", "localhost:"+*port)
        if err != nil {
                log.Fatal(err)
        }   

        for {
                conn, err := listener.Accept()
                if err != nil {
                        log.Print(err) // e.g., connection aborted
                        continue
                }   
                go handleConn(conn) //新建goroutines處理連接
        }   
}

func handleConn(c net.Conn) {
        defer c.Close()
        for {
                _, err := io.WriteString(c, time.Now().Format("15:04:05\n"))
                if err != nil {
                        return // e.g., client disconnected
                }   
                time.Sleep(1 * time.Second)
        }   
}

clockwall.go

// Netcat1 is a read-only TCP client.
package main

import (
        "io"
        "log"
        "net"
        "os"
        "strings"
        "time"
)

func main() {
        for _, v := range os.Args[1:] {
                keyValue := strings.Split(v, "=")
                go connTcp(keyValue[1])
        }   
        for {
                time.Sleep(1 * time.Second)
        }   
}

func connTcp(uri string) {
        conn, err := net.Dial("tcp", uri)
        if err != nil {
                log.Fatal(err)
        }   
        defer conn.Close()
        mustCopy(os.Stdout, conn)

}

func mustCopy(dst io.Writer, src io.Reader) {
        if _, err := io.Copy(dst, src); err != nil {
                log.Fatal(err)
        }   
}

技術分享圖片  

  

[日常] Go語言聖經--示例: 並發的Clock服務習題