【原】使用Golang语言编写echo程序

网络教程的echo程序,在server断开链接的时候,会出现卡死的情况,如何防止这样的问题出现呢?

我自己优化了一把,异步的echo程序,在client端进行容错判断,在server重启的时候能够进行重新链接。

啥也不说了,上代码。 

//server.go 

package main

import (
    "bufio"
    "fmt"
    "net"
)

func Echo(c net.Conn) {
    defer c.Close()
    for {
        line, err := bufio.NewReader(c).ReadString('\n')
        if err != nil {
            fmt.Printf("Failure to read:%s\n", err.Error())
            return
        }
        _, err = c.Write([]byte(line))
        if err != nil {
            fmt.Printf("Failure to write: %s\n", err.Error())
            return
        }
    }
}

func main() {
    fmt.Printf("Server is ready...\n")
    l, err := net.Listen("tcp"":8053")
    if err != nil {
        fmt.Printf("Failure to listen: %s\n", err.Error())
    }

    for {
        if c, err := l.Accept(); err == nil {
            go Echo(c) //new thread
        }
    }
}

 //client.go

package main

import (
    "bufio"
    "fmt"
    "net"
    "os"
    "time"
)

type Clienter struct {
    client  net.Conn
    isAlive bool
    SendStr chan string
    RecvStr chan string
}

func (c *Clienter) Connect() bool {
    if c.isAlive {
        return true
    } else {
        var err error
        c.client, err = net.Dial("tcp""127.0.0.1:8053")
        if err != nil {
            fmt.Printf("Failure to connet:%s\n", err.Error())
            return false
        }
        c.isAlive = true
    }
    return true
}

func (c *Clienter) Echo() {
    line := <-c.SendStr
    c.client.Write([]byte(line))
    buf := make([]byte1024)
    n, err := c.client.Read(buf)
    if err != nil {
        c.RecvStr <- string("Server close...")
        c.client.Close()
        c.isAlive = false
        return
    }
    time.Sleep(1 * time.Second)
    c.RecvStr <- string(buf[0:n])
}

func Work(tc *Clienter) {
    if !tc.isAlive {
        if tc.Connect() {
            tc.Echo()
        } else {
            <-tc.SendStr
            tc.RecvStr <- string("Server close...")
        }
    } else {
        tc.Echo()
    }
}
func main() {
    //defer client.Close()
    var tc Clienter
    tc.SendStr = make(chan string)
    tc.RecvStr = make(chan string)
    if !tc.Connect() {
        return
    }
    r := bufio.NewReader(os.Stdin)
    for {
        switch line, ok := r.ReadString('\n'); true {
        case ok != nil:
            fmt.Printf("bye bye!\n")
            return
        default:
            go Work(&tc)
            tc.SendStr <- line
            s := <-tc.RecvStr
            fmt.Printf("back:%s\n", s)
        }
    }

原文地址:https://www.cnblogs.com/zhangqingping/p/2742356.html