为了账号安全,请及时绑定邮箱和手机立即绑定

改进网络代码而不使用 goto 语句来处理断开的连接情况

改进网络代码而不使用 goto 语句来处理断开的连接情况

Go
HUX布斯 2021-08-23 16:01:22
如何在没有 goto 语句的情况下改进我的代码?我的函数是从服务器读取数据并将数据发送到另一个处理数据的函数,我不得不添加一个 goto 语句来处理断开的连接情况,我没有找到更好的方法来做到这一点。你能帮我一些建议吗?func Reader(source string, proto string, chOutput chan string) {init:    fmt.Println("Conectando con Source:", source)    conn, err := net.Dial(proto, source)    if err != nil {        fmt.Println("Error:", err.Error())    }    defer conn.Close()    reader := bufio.NewReader(conn)    for {        line, err := reader.ReadString('\n')        if err != nil {            fmt.Println("Error:", err.Error())            time.Sleep(1 * time.Second)            goto init        }        fmt.Println("Enviando dato a Buffer:", line)        chOutput <- line    }}我的功能是一个 goroutine :func main(){    mychan:= make(chan string)    go Reader(source, proto, mychan)    go Process(mychan)    ...}goto 或标签是解决重试连接的最佳方法吗?有没有另一种标准的方法来做到这一点?
查看完整描述

2 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

您可以通过引入外循环来消除 goto。如果打开连接出错,则继续外循环。如果读取行出错,则跳出内部循环。


完成后关闭连接。defer 在函数返回之前不会执行。


func Reader(source string, proto string, chOutput chan string) {

  for {

    fmt.Println("Conectando con Source:", source)

    conn, err := net.Dial(proto, source)

    if err != nil {

        fmt.Println("Error:", err.Error())

        time.Sleep(1 * time.Second)

        continue

    }

    reader := bufio.NewReader(conn)

    for {

        line, err := reader.ReadString('\n')

        if err != nil {

            fmt.Println("Error:", err.Error())

            conn.Close()

            time.Sleep(1 * time.Second)

            break

        }

        fmt.Println("Enviando dato a Buffer:", line)

        chOutput <- line

    }

  }

}

考虑在连接失败时使用指数退避:


func Reader(source string, proto string, chOutput chan string) {

  sleep := time.Second

  for {

    fmt.Println("Conectando con Source:", source)

    conn, err := net.Dial(proto, source)

    if err != nil {

        fmt.Println("Error:", err.Error())

        sleep *= 2 // exponential backoff

        if sleep > time.Minute {

           sleep = time.Minute

        }

        time.Sleep(sleep)

        continue

    }

    sleep = time.Second // Reset on success.

    reader := bufio.NewReader(conn)

    for {

        line, err := reader.ReadString('\n')

        if err != nil {

            fmt.Println("Error:", err.Error())

            conn.Close()

            time.Sleep(sleep)

            break

        }

        fmt.Println("Enviando dato a Buffer:", line)

        chOutput <- line

    }

  }

}


查看完整回答
反对 回复 2021-08-23
  • 2 回答
  • 0 关注
  • 219 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信