使用Golang语言编写echo程序

时间:2022-05-05
本文章向大家介绍使用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:%sn", err.Error())
 return
        }
        _, err = c.Write([]byte(line))
 if err != nil {
            fmt.Printf("Failure to write: %sn", 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: %sn", 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:%sn", err.Error())
 return false
        }
        c.isAlive = true
    }
 return true
}

func (c *Clienter) Echo() {
    line := <-c.SendStr
    c.client.Write([]byte(line))
    buf := make([]byte, 1024)
    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:%sn", s)
        }
    }
}