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

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

展开原文

原文

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?

dongshi7433
dongshi7433 将来的读取将失败,是的,但是可以安全地重试某些操作。在某些情况下,如果您使用的是更高级别的库(例如net/http),则会自动重试某些操作。
大约一年之前 回复

3个回答

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.

dougu9895
dougu9895 不,您不会看到从tcp连接读取的任何临时错误。 查看io.ReadFull,它可以完成您描述的任务。
大约一年之前 回复
duanan1946
duanan1946 我从被劫持的http连接中获取了net.Conn,我想从该连接中读取固定(已知)数量的字节。 我不知道在读取这些字节的代码中必须处理哪些错误。 我的问题基本上是“如何从连接中正确读取n个字节?” 我知道可能会发生短读,因此我需要循环来收集字节。 但是我的错误处理应该看起来像上面的接受示例吗? 还是我应该放弃第一个错误? 或者是其他东西?
大约一年之前 回复
dpoxk64080
dpoxk64080 您期望什么“可重试”错误? net.Conn不是实现,但是例如* TCPConn不会因读取可重试而产生任何错误; 当然,除了超时,但在这种情况下,您需要检查超时,而不是“临时”。
大约一年之前 回复
doudu5029
doudu5029 我的问题是关于已经接受连接后的Read()调用。 我想我会在那儿使用类似的重试循环吗?
大约一年之前 回复

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
 }



查看网络软件包的特定错误类型 https://golang.org/pkg/net/#OpError </ p>

它提供了特定的 Temporary()</ code >找出是否是非终端错误的方法。</ p>

要手动找出哪个错误是 Temporary </ code>,您必须仔细检查 net,os和其他一些内部软件包。</ p>

要以编程方式检查临时错误,您可以声明自己的本地临时接口{Temporary()bool} </ code>, 或者您可以依靠网络软件包 https://golang.org/pkg/net提供的界面 /#Error </ p>

OpError.Temporary </ code>方法测试其内部错误是否实现了 net.temporary </ code>接口(< a href =“ https://golang.org/src/net/net.go?s=16056:16090#L501” rel =“ no 请遵循noreferrer“> https://golang.org/src/net/net.go?s=16056:16090#L501 ),如果是,则将调用结果返回到 Temporary()< / code>内部错误,例如 https:// golang.org/src/net/net.go?s=19122:19157#L605 。</ p>

我不确定您正在考虑哪个读重试,但是内部fd .read方法再次实现重试
https://golang.org/src /internal/poll/fd_unix.go#L165 </ p>
</ div>

展开原文

原文

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

dongxiaoying5882
dongxiaoying5882 不能保证所有错误都是net.Error,但是您可以通过类型断言来实现,所以没关系。 如果不是net.Error,则不是要检查“临时”错误,任何进一步的猜测都需要对情况有确切的了解。
大约一年之前 回复
douweng9427
douweng9427 确实。 忘记了 是否可以保证网络错误实现了该接口? 我在文档中找不到它。 添加了一些关于您的评论的评论
大约一年之前 回复
duanliujie8639
duanliujie8639 尽管OpError具有Temporary方法,但它不是唯一的方法,您应该在寻找net.Error(没有公共net.Temporary接口`)
大约一年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐