TCP客户端可以在读取超时后接收数据吗?

时间:2018-03-19 12:30:43

标签: go tcp

我在golang中创建一个tcp连接池,并设置每个连接保持活动状态,当我从池中获得连接时,我将通过SetDeadline函数设置10秒超时。现在我想知道,如果在读取连接后发生超时错误,服务器在此之后向我发送消息,该消息是否会被放入我的连接接收缓冲区?我会在下次阅读时得到这个消息吗?如果是这样,我该如何处理超时错误?关闭连接并创建一个新连接?

1 个答案:

答案 0 :(得分:1)

  

如果在此点之后从连接和服务器发送消息后读取超时错误,该消息是否会被放入我的连接接收缓冲区?

如果你没有关闭连接,是的。

  

下次阅读时我会收到该消息吗?

是的,如果您重置截止日期。虽然这确实提出了为什么你首先设置超时的问题。

package main

import (
    "fmt"
    "io"
    "log"
    "net"
    "time"
)

func main() {
    l, err := net.Listen("tcp", "127.0.0.1:3001")
    check(err)

    go slowServer(l)

    conn, err := net.Dial("tcp", "127.0.0.1:3001")
    check(err)
    conn.SetDeadline(time.Now().Add(time.Second))

    b := make([]byte, 512)

    n, err := conn.Read(b)
    fmt.Printf("%q, %v\n", b[:n], err) // "", i/o timeout

    // Reset deadline
    conn.SetDeadline(time.Now().Add(2 * time.Second))

    n, err = conn.Read(b)
    fmt.Printf("%q, %v\n", b[:n], err) // "hello world", <nil>
}

func slowServer(l net.Listener) {
    conn, err := l.Accept()
    check(err)

    time.Sleep(2 * time.Second)
    io.WriteString(conn, "hello world")
    conn.Close()
}

func check(err error) {
    if err != nil {
            log.Fatal(err)
    }
}

// "", read tcp 127.0.0.1:50488->127.0.0.1:3001: i/o timeout
// "hello world", <nil>

在操场上试试:https://play.golang.org/p/Id60hHK7tKF