golang简易版TCP client server 篇中简单列了下golang下的c/s模式代码,不过遇到 server 端异常时, client端也就自动退出了,这里再给出一段自动重连的代码,实现无论server端如何,client始装循环下去。所以本篇的重点是client端的代码

server 端代码

 1package main
 2import (
 3    "fmt"
 4    "net"
 5    "os"
 6    "strings"
 7    "time"
 8)
 9func checkError(err error) {
10    if err != nil {
11        fmt.Println(err)
12        os.Exit(1)
13    }
14}
15func handleClient(conn net.Conn) {
16    conn.SetReadDeadline(time.Now().Add(3 * time.Minute))
17    request := make([]byte,1024)
18    defer conn.Close()
19    for {
20        recv_len,err := conn.Read(request)
21        if err != nil {
22            fmt.Println(err)
23            break
24        }
25        if recv_len == 0 {
26            break
27        }
28        recvData := strings.TrimSpace(string(request[:recv_len]))
29        fmt.Println("recv_len : ",recv_len)
30        fmt.Println("recv_data : " + recvData)
31        daytime := time.Now().String()
32        conn.Write([]byte(daytime + "\n"))
33        request = make([]byte,1024)
34    }
35}
36func main() {
37    bindInfo := ":10000"
38    tcpAddr,err := net.ResolveTCPAddr("tcp4",bindInfo)
39    checkError(err)
40    listener,err := net.ListenTCP("tcp",tcpAddr)
41    checkError(err)
42    for {
43        cc,err := listener.Accept()
44        if err != nil {
45            continue
46        }
47        go handleClient(cc)
48    }
49}

client端代码

 1package main
 2import (
 3    "net"
 4    "fmt"
 5    "bufio"
 6    "time"
 7)
 8func doTask(conn net.Conn) {
 9    for {
10        fmt.Fprintf(conn,"test msg\n")
11        msg,err := bufio.NewReader(conn).ReadString('\n')
12        if err != nil {
13            fmt.Println("recv data error")
14            break
15        }else{
16            fmt.Println("recv msg : ",msg)
17        }
18        time.Sleep(1 * time.Second)
19    }
20}
21func main() {
22    hostInfo := "127.0.0.1:10000"
23    for {
24        conn,err := net.Dial("tcp",hostInfo)
25        fmt.Print("connect (",hostInfo)
26        if err != nil {
27            fmt.Println(") fail")
28        }else{
29            fmt.Println(") ok")
30            defer conn.Close()
31            doTask(conn)
32        }
33        time.Sleep(3 * time.Second)
34    }
35}

具体运行效果我就不再黏了。

后记:另外需要注意一点的是,如果有用到log模块,需要特别注意 log.Fatal和log.Panic类方法,具体可以参看我的另一篇博文 golang下慎用log.Fatal和log.Panic