wangjun
wangjun

Reputation: 709

Can TCP clients receive data after a read timeout?

I create a tcp connection pool in golang and set every connection to keep alive, when I get a connection from pool, I will set a 10 seconds timeout by SetDeadline function. Now I want to know, if a timeout error occur after reading from a connection and server send message to me after this point, will the message be put into my connection receive buffer? Will I get the message in next reading? If so, how should I handle the timeout error? Close the connection and create a new one?

Upvotes: 0

Views: 1897

Answers (1)

Peter
Peter

Reputation: 31751

If a timeout error occur after reading from a connection and server send message to me after this point, will the message be put into my connection receive buffer?

If you don't close the connection, yes.

Will I get the message in next reading?

Yes, if you reset the deadline. Although this does beg the question why you set a timeout in the first place.

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>

Try it on the playground: https://play.golang.org/p/Id60hHK7tKF

Upvotes: 1

Related Questions