簡體   English   中英

net.Conn 是否存在可恢復的讀取錯誤?

[英]Are there recoverable read errors for a net.Conn?

如果net.Conn .Read()方法返回錯誤,這是否意味着將來的讀取也會因錯誤而失敗? 或者是否存在可恢復的錯誤? 如果是這樣,我怎么知道是否/何時重試讀取?

通常,您不會因可重試的conn.Read操作而出現任何錯誤。 io.Reader接口的大多數用途都假定所有錯誤都是最終的。

任何保證可重試的net包錯誤都將符合net.Error接口,並公開一個Temporary方法。

這最常用於Accept循環,就像 http 包中的這個釋義示例

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
    }
}

任何其他可能的情況都需要單獨處理,並了解手頭的協議和情況。

超時是從net.TCPConn讀取的唯一可恢復錯誤,並且只有在連接上設置讀取截止時間時才會返回該錯誤。

使用Error.Temporary() ,以檢查可能解決在重試和錯誤Error.Timeout()來檢查超時:

 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
 }

具體錯誤類型見net包https://golang.org/pkg/net/#OpError

它提供了一個特定的Temporary()方法來確定它是否是非終端錯誤。

要手動確定哪個錯誤是Temporary錯誤,您必須檢查 net、os 和其他一些內部包中定義的每個錯誤。

要以編程方式檢查臨時錯誤,您可以聲明自己的本地temporary interface{ Temporary() bool } ,或者您可以依賴網絡包https://golang.org/pkg/net/#Error提供的此接口

OpError.Temporary方法測試其內部錯誤是否實現了net.temporary接口( https://golang.org/src/net/net.go?s=16056:16090#L501 ),如果是,則返回結果調用Temporary()內部錯誤,例如https://golang.org/src/net/net.go?s=19122:19157#L605

我不確定您正在考慮哪個讀取重試,但是,內部 fd.read 方法實現了再次重試https://golang.org/src/internal/poll/fd_unix.go#L165

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM