zoukankan      html  css  js  c++  java
  • 【原】使用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)
            }
        }

  • 相关阅读:
    Java面试题:==运算符与equals方法的区别
    STS或eclipse中导入新项目出现红色感叹号红色叉叉的问题
    SpringBoot+SpringDataJpa快速上手(基本CRUD)
    Java-数组拷贝
    Java-数组拷贝
    最小高度树Java版本(力扣)
    macOS安装minikube
    测试面试LeetCode系列:字符串的左旋转
    测试面试LeetCode系列:按既定顺序创建目标数组
    systemd的文件描述符限制引发的问题
  • 原文地址:https://www.cnblogs.com/zhangqingping/p/2742356.html
Copyright © 2011-2022 走看看