doujiazong0322
2019-09-13 12:54
浏览 101

net.Conn是否存在可恢复的读取错误?

If the .Read() method of a net.Conn returns an error, does this imply that future reads also will fail with an error? Or are there recoverable errors? If so, how do I know whether/when to retry reads?

图片转代码服务由CSDN问答提供 功能建议

如果.Read()方法 /golang.org/pkg/net/#Conn“ rel =” nofollow noreferrer“> net.Conn 返回错误,这是否意味着将来的读取也会因错误而失败? 还是有可恢复的错误? 如果是这样,我如何知道是否/何时重试读取?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • doushan6692 2019-09-13 13:31

    See the specific error type of the net package https://golang.org/pkg/net/#OpError

    It provides a specific Temporary() method to figure out if it is a non-terminal error.

    To manually figure out which error is Temporary you have to go through each defined error within the net, os and some other internal packages.

    To programmatically check for a temporary error, you might declare your own local temporary interface{ Temporary() bool }, or you can rely on this interface provided by the net package https://golang.org/pkg/net/#Error

    The OpError.Temporary method test if its internal error implements the net.temporary interface (https://golang.org/src/net/net.go?s=16056:16090#L501), and if so returns the result of the call to Temporary() of the internal error, for example https://golang.org/src/net/net.go?s=19122:19157#L605.

    I am unsure which read retry you are thinking about, however, internal fd.read methods implements retries for eagain https://golang.org/src/internal/poll/fd_unix.go#L165

    点赞 评论
  • dsag14654 2019-09-13 16:24

    In general, you're not going to have any errors from a conn.Read operation that can be retried. Most uses of the io.Reader interface will assume that all errors are final.

    Any net package errors that are assured to be retry-able will conform to the net.Error interface, and expose a Temporary method.

    This is most often used in an Accept loop, like this paraphrased example from the http package

    for {
        rw, e := l.Accept()
        if e != nil {
            if ne, ok := e.(net.Error); ok && ne.Temporary() {
                if tempDelay == 0 {
                    tempDelay = 5 * time.Millisecond
                } else {
                    tempDelay *= 2
                }
                if max := 1 * time.Second; tempDelay > max {
                    tempDelay = max
                }
                time.Sleep(tempDelay)
                continue
            }
            return e
        }
    }
    

    Any other possible cases need to be handled on an individual basis, with knowledge of the protocol and situation at hand.

    点赞 评论
  • douou8954 2019-09-14 00:31

    Timeout is the only recoverable error on read from a net.Conn and that error will only be returned when a read deadline is set on the connection.

    Use Error.Timeout() to check for timeouts:

     n, err := c.Read(buf)
     // process buf[:n] bytes
     if e.(net.Error); ok && e.Timeout() && e.Temporary() {
        // handle recoverable read deadline expiration
     } else if err != nil {
        // handle other errors
     }
    
    点赞 评论

相关推荐 更多相似问题