• 【go】golang网络通信超时设置


    网络通信中,为了防止长时间无响应的情况,经常会用到网络连接超时、读写超时的设置。

    本文结合例子简介golang的连接超时和读写超时设置。

    1.超时设置

    1.1 连接超时

    func DialTimeout(network, address string, timeout time.Duration) (Conn, error) 

    第三个参数timeout可以用来设置连接超时设置。
    如果超过timeout的指定的时间,连接没有完成,会返回超时错误。

    1.2 读写超时

    Conn定义中,包括读写的超时时间设置。

    type Conn interface {
        // SetDeadline sets the read and write deadlines associated
        // with the connection. It is equivalent to calling both
        // SetReadDeadline and SetWriteDeadline.
        //
        ... ...
        SetDeadline(t time.Time) error
    
        // SetReadDeadline sets the deadline for future Read calls
        // and any currently-blocked Read call.
        // A zero value for t means Read will not time out.
        SetReadDeadline(t time.Time) error
    
        // SetWriteDeadline sets the deadline for future Write calls
        // and any currently-blocked Write call.
        // Even if write times out, it may return n > 0, indicating that
        // some of the data was successfully written.
        // A zero value for t means Write will not time out.
        SetWriteDeadline(t time.Time) error
    }

    通过上面的函数说明,可以得知,这里的参数t是一个未来的时间点,所以每次读或写之前,都要调用SetXXX重新设置超时时间,

    如果只设置一次,就会出现总是超时的问题。

    2.例子

    2.1 server

    server端监听连接,如果收到连接请求,就是创建一个goroutine负责这个连接的数据收发。

    为了测试超时,我们在写操作之前,sleep 3s。

    package main
    
    import (
            "net"
            "log"
            "time"
    )
    
    func main() {
            addr := "0.0.0.0:8080"
    
            tcpAddr, err := net.ResolveTCPAddr("tcp",addr)
    
            if err != nil {
                    log.Fatalf("net.ResovleTCPAddr fail:%s", addr)
            }
    
            listener, err := net.ListenTCP("tcp", tcpAddr)
            if err != nil {
                    log.Fatalf("listen %s fail: %s", addr, err)
            } else {
                    log.Println("listening", addr)
            }
    
    
            for {
                    conn, err := listener.Accept()
                    if err != nil {
                            log.Println("listener.Accept error:", err)
                            continue
                    }
    
                    go handleConnection(conn)
            }
    
    }
    
    
    func handleConnection(conn net.Conn) {
            defer conn.Close()
    
            var buffer []byte = []byte("You are welcome. I'm server.")
    
    
            for {
                    time.Sleep(3*time.Second)// sleep 3s
                    n, err := conn.Write(buffer)
                    if err != nil {
                            log.Println("Write error:", err)
                            break
                    }
                    log.Println("send:", n)
            }
    
            log.Println("connetion end")
    
    }

    2.2 client

    client建立连接时,使用的超时时间是3s。

    创建连接成功后,设置连接的读超时。
    每次读之前,都重新设置超时时间。

    package main
    
    import (
            "log"
            "net"
            "os"
            "time"
    )
    
    func main() {
            connTimeout := 3*time.Second
            conn, err := net.DialTimeout("tcp", "127.0.0.1:8080", connTimeout)  // 3s timeout
            if err != nil {
                    log.Println("dial failed:", err)
                    os.Exit(1)
            }
            defer conn.Close()
    
            readTimeout := 2*time.Second
    
            buffer := make([]byte, 512)
    
            for {
                    err = conn.SetReadDeadline(time.Now().Add(readTimeout)) // timeout
                    if err != nil {
                            log.Println("setReadDeadline failed:", err)
                    }
    
                    n, err := conn.Read(buffer)
                    if err != nil {
                            log.Println("Read failed:", err)
                            //break
                    }
    
                    log.Println("count:", n, "msg:", string(buffer))
            }
      
    }

    输出结果

    2019/05/12 16:18:19 Read failed: read tcp 127.0.0.1:51718->127.0.0.1:8080: i/o timeout
    2019/05/12 16:18:19 count: 0 msg:
    2019/05/12 16:18:20 count: 28 msg: You are welcome. I'm server.
    2019/05/12 16:18:22 Read failed: read tcp 127.0.0.1:51718->127.0.0.1:8080: i/o timeout
    2019/05/12 16:18:22 count: 0 msg: You are welcome. I'm server.
    2019/05/12 16:18:23 count: 28 msg: You are welcome. I'm server.
    2019/05/12 16:18:25 Read failed: read tcp 127.0.0.1:51718->127.0.0.1:8080: i/o timeout
    2019/05/12 16:18:25 count: 0 msg: You are welcome. I'm server.
    2019/05/12 16:18:26 count: 28 msg: You are welcome. I'm server.
  • 相关阅读:
    Sharepoint 2010:基于当前用户判断访问列表项目的权限 Determine access to SPListItem based on a Current User
    vs2010修改sharepoint部署站点
    写入数据内存溢出的错误ErrorCode=2147217900解决
    新鲜网络故障:网线测试器测试,居然2,3信号灯齐亮!解决
    CuteEditor出错了,居然是没有了lic文件
    路由表的故障?如何理解设置
    MSSQL如何快速清除数据库日志转,经实践有效
    iis中web站点无法启动:另一程序正在使用该文件,进程无法访问解决
    二次开发图片浏览系统应用Lightbox image viewer 2.03a并带javascript的字符串处理
    asp session丢失的分析和解决方法
  • 原文地址:https://www.cnblogs.com/opensmarty/p/16798189.html
Copyright © 2020-2023  润新知