使用GOLANG的协程和sync.WaitGroup模拟cli获取各个城市的时间

服务器启动方式: 

./clock-server -port 8000 &

./clock-server -port 8001 &

./clock-server -port 8002 &

这样就模拟启动了三个城市的服务器

代码:

package main

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

//这里用flag包获取一下端口参数
var port = flag.Int("port", 8000, "listen port: -port 8000")
func init() {
	flag.Parse()
}

func main() {
	addr := fmt.Sprintf("localhost:%d", *port)
	fmt.Println(addr)
	listenner, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatal(err)
	}
	for {
		conn, err := listenner.Accept()
		if err != nil {
			log.Print(err)
			continue
		}

		go handleConn(conn) //一个协程处理一个连接
	}

}

func handleConn(c net.Conn) {
	defer c.Close()	
	for {
		_, err := io.WriteString(c, time.Now().Format("15:04:05\n")) //把时间返回给客户端
		if err != nil {
			return
		}

		time.Sleep(1 * time.Second)
	}
}

 

客户端启动方式:go run clock-cli.go NewYork=localhost:8000 Youko=localhost:8001 London=localhost:8002

客户端代码用单一工厂模式创建一个GetClocks对象,用AddCity方法添加城市,用Start()方法启动与服务器的连接请求,每一个城市使用一个协程,主协程使用wg.Wait()等待所以协程返回,然后才从Start()方法返回。代码如下:

package main

import (
	"bufio"
	"errors"
	"fmt"
	"log"
	"net"
	"os"
	"strings"
	"sync"
	"time"
)

type GetClocks struct {
	Cities []string //city slice
	Addrs  []string //city's addr:port
	Times  []string //city's clock
	cnt    int      //total cities

	wg sync.WaitGroup //wait for all query city return
}

//new a struct
func NewGetClocks() *GetClocks {
	clocks := new(GetClocks)
	clocks.Cities = make([]string, 0)
	clocks.Addrs = make([]string, 0)
	clocks.Times = make([]string, 0)

	return clocks
}

func (clocks *GetClocks) AddCity(city, address string) {
	clocks.Cities = append(clocks.Cities, city)
	clocks.Addrs = append(clocks.Addrs, address)
	clocks.Times = append(clocks.Times, "null")
	clocks.cnt++
}

func (clocks *GetClocks) Start() error {
	if clocks.cnt != 0 {
		for i := 0; i < clocks.cnt; i++ {
			clocks.wg.Add(1) //启动协程之前先Add(1)
			go func(i int) {
				defer clocks.wg.Done() //协程返回时记得Done
				var (
					conn net.Conn
					err  error
				)
				conn, err = net.DialTimeout("tcp", clocks.Addrs[i], 5*time.Second)
				if err != nil {
					clocks.Times[i] = "connect err!"
					log.Printf("Connect to %v, address: %v failed\n",
						clocks.Cities[i], clocks.Addrs[i])
					return
				}
				defer conn.Close()

				//读取服务器返回的一行,就结束
				if clocks.Times[i], err = bufio.NewReader(conn).ReadString('\n'); err != nil {
					clocks.Times[i] = "get err!"
					log.Printf("%v, address: %v get clocke failed:%v\n", clocks.Cities[i], clocks.Addrs[i], err)
				}

			}(i)
		}

		clocks.wg.Wait()

		return nil
	}

	return errors.New("No any city!")
}

//打印取得的各个城市的时间
func (clocks *GetClocks) Display() {
	for i, city := range clocks.Cities {
		fmt.Printf("%s : %s\n", city, clocks.Times[i])
	}
}

//./app NewYork=localhost:8000 youko=localhost:8001 london=localhost:8002
func main() {

	clocks := NewGetClocks()
	for _, argv := range os.Args[1:] {
		city_addr := strings.Split(argv, "=")
		clocks.AddCity(city_addr[0], city_addr[1])
	}

	clocks.Start()
	clocks.Display()
}

运行结果:

root@myubuntu:go-websocket# go run clock-cli.go NewYork=localhost:8000 Youko=localhost:8001 London=localhost:8002
NewYork : 23:40:13

Youko : 23:40:13

London : 23:40:13

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值