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

如何在没有 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 或标签是解决重试连接的最佳方法吗?有没有另一种标准的方法来做到这一点?


HUX布斯
浏览 220回答 2
2回答

拉风的咖菲猫

您可以通过引入外循环来消除 goto。如果打开连接出错,则继续外循环。如果读取行出错,则跳出内部循环。完成后关闭连接。defer 在函数返回之前不会执行。func Reader(source string, proto string, chOutput chan string) {&nbsp; for {&nbsp; &nbsp; fmt.Println("Conectando con Source:", source)&nbsp; &nbsp; conn, err := net.Dial(proto, source)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Error:", err.Error())&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(1 * time.Second)&nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; }&nbsp; &nbsp; reader := bufio.NewReader(conn)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; line, err := reader.ReadString('\n')&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Error:", err.Error())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.Close()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(1 * time.Second)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Enviando dato a Buffer:", line)&nbsp; &nbsp; &nbsp; &nbsp; chOutput <- line&nbsp; &nbsp; }&nbsp; }}考虑在连接失败时使用指数退避:func Reader(source string, proto string, chOutput chan string) {&nbsp; sleep := time.Second&nbsp; for {&nbsp; &nbsp; fmt.Println("Conectando con Source:", source)&nbsp; &nbsp; conn, err := net.Dial(proto, source)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Error:", err.Error())&nbsp; &nbsp; &nbsp; &nbsp; sleep *= 2 // exponential backoff&nbsp; &nbsp; &nbsp; &nbsp; if sleep > time.Minute {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sleep = time.Minute&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(sleep)&nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; }&nbsp; &nbsp; sleep = time.Second // Reset on success.&nbsp; &nbsp; reader := bufio.NewReader(conn)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; line, err := reader.ReadString('\n')&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Error:", err.Error())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; conn.Close()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(sleep)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Enviando dato a Buffer:", line)&nbsp; &nbsp; &nbsp; &nbsp; chOutput <- line&nbsp; &nbsp; }&nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP