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.

原文地址:https://www.cnblogs.com/lanyangsh/p/10852755.html

时间: 2024-10-13 22:05:54

golang网络通信超时设置的相关文章

Outlook Web App 客户端超时设置

这篇文章我们讨论一下,OWA 2013在公共和私人的电脑是如何启用和配置. Exchange 2013 Outlook Web App (OWA) 登录页不再允许用户选择无论他们正在使用公共的或私人的计算机.默认情况下,OWA 2013 是假定用户使用的是私人计算机,如使用超时的 8 小时.出于安全考虑,用户处于非活动状态之前要求用户重新登录. 在 Set-OWAVirtualDirectory cmdlet 中 LogonPagePublicPrivateSelectionEnabled 参数

org.apache.http.client.HttpClient; HttpClient 4.3超时设置

可用的code public static String doPost(String url, String params, String contentType) /*throws IOException */{ CloseableHttpClient client = HttpClients.createDefault(); RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(httpSoTimeout)

connect socket的超时设置

最近项目中,有个需求是检测某ip地址是否是通的,使用了socket的connect函数.但是,当ip地址写错的话,connect就会一直阻塞在那里,大概2.3分钟才能返回连接失败.这对于用户来说是不可接受的.下面的文章介绍了两种方法实现这种超时设置: 转自http://blog.csdn.net/ast_224/article/details/2957294  connect超时: 目前各平台通用的设置socket connect超时的办法是通过select(),具体方法如下: 1.建立sock

添加MySql数据库超时设置的相关问题

最近在工作中, 遇到MySql数据库连接超时的问题,申同事帮忙解决了一下,看到原来的MySqlHelper里面没有封装相关的超时方法,就添加了一个,我在这里记录了一下,希望对像我一样入门级的程序员有所帮助: 如下方法: Private int ExecuteScalarBySql(string sqlstr) { try{ using((MySqlConnection mysqlconn)=new MySqlConnection(Config.ConnectionStrings)) { mysq

使用Jsoup获取网页内容超时设置

使用Jsoup获取网页内容超时设置 最近使用Jsoup来抓取网页,并对网页进行解析,发现很好用.在抓取过程中遇到一个问题,有些页面总是报Timeout异常,开始想是不是被抓取网站对IP进行了限制,后来发现用HttpClient可以获取到内容. 原来我最开始使用Jsoup.connect(url).get();方法获取网页内容,这种方式使用的是默认超时时间3秒. 原来Jsoup是可以设置超时的,修改成如下就可以了: Jsoup.connect(url).timeout(30000).get();

你应该知道的那些超时设置或默认参数 good

defaultStatementTimeout Sets the number of seconds the driver will wait for a response from the database. Any positive integer Not Set (null) http://www.mybatis.org/mybatis-3/configuration.html 存储介质 Redis Java-Driver Jedis 连接池:Jedis的连接池设计基于 Apache Co

libcurl多线程超时设置不安全(转)

from http://www.cnblogs.com/kex1n/p/4135263.html (1), 超时(timeout) libcurl 是 一个很不错的库,支持http,ftp等很多的协议.使用库最大的心得就是,不仔细看文档,仅仅看着例子就写程序,是一件危险的事情.我的程序崩溃了,我 怀疑是自己代码写的问题,后来发现是库没用对.不仔细看文档(有时候文档本身也比较差劲,这时除了看仔细外,还要多动脑子,考虑它是怎么实现的),后果很 严重.不加思索的使用别人的库或者代码,有时候很惬意,但是

基础入门_Python-模块和包.Gevent异步/状态获取/超时设置/猴子补丁?

简单介绍: 说明: Gevent是一个基于libev的并发库,为各种并发和网络相关的任务提供了整洁的API 快速安装: pip install --upgrade gevent 主要模式: 说明: Greenlet以C扩展模块形式接入PY轻量级协程,它们运行于主进程内部,被协作式的调度,且不同于multiprocessing和threading等真正的并行执行,它在同一时刻只能有一个协程在运行 公有方法 gevent.spawn(cls, *args, **kwargs) 创建一个Greenle

Delphi使用进行post数据时超时设置

因项目需要进行http的post提交数据,开始时用indy的idHttp组件,但是测试时发现当网络中断(如拔掉网线),idHttp的超时设置无效果,要等20秒才提示超时(参考网上的做法,将indy9升级到indy10,且设置了idHttp的connetTimeout,ReadTimeout属性,均无效果). 后来发现用ICS组件THttpCli可以很好的控制提交超时,达到我的目的. ICS版本:OverbyteIcsV7Gold 下载:http://www.overbyte.be/arch/Ov