3 回答

TA貢獻1820條經驗 獲得超10個贊
選項是關閉連接或將讀取截止日期設置為過去的某個時間。無論哪種方式,讀取連接都會返回錯誤。
處理這些錯誤的最簡單方法是統一處理網絡連接上讀取返回的所有錯誤:關閉連接,清理與連接關聯的資源,然后繼續。關閉連接兩次就可以了。
func recv(c net.Conn, msg chan string) {
? ? defer close(msg) // Notify main goroutine that recv is done.
? ? defer c.Close()? // Release resources.
? ? input := bufio.NewScanner(c)
? ? // Loop reading lines until read on c returns an error.
? ? // These errors include io.EOF (normal close by the peer),
? ? // the error caused by the main goroutine closing the connection
? ? // and other networking errors.
? ? for input.Scan() {
? ? ? ? msg <- input.Text()
? ? }
}
// main
conn, err := s.Accept()
if err != nil {
? ? // handle error
}
msg := make(chan string)
go recv(conn, msg)
for {
? ? select {
? ? case m, ok := <-msg:
? ? ? ? if !ok {
? ? ? ? ? ? // The recv goroutine closed the channel and the connection.
? ? ? ? ? ? return
? ? ? ? }
? ? ? ? fmt.Println(m)
? ? case <-timeout:
? ? ? ? // Closing the connection causes the recv goroutine to break
? ? ? ? // out of the loop. If the recv goroutine received a line of?
? ? ? ? // text and has yet sent the text to the msg channel, then?
? ? ? ? // a return from main at this point will cause the recv goroutine
? ? ? ? // to block forever. To avoid this, continue looping until until
? ? ? ? // the recv goroutine signals that it's done by closing the msg
? ? ? ? // channel.
? ? ? ? conn.Close()
? ? }
}
}
應用程序可以記錄它正在關閉連接并在該點之后以特殊方式處理讀取錯誤,但只有在這種情況下應用程序需要做一些特殊的事情時才這樣做。

TA貢獻2016條經驗 獲得超9個贊
有一些錯誤建議單獨處理,例如:
EOF:一條長收到的消息已經讀完,一切正常,繼續。
“一個現有的連接被遠程主機強行關閉”:客戶端關閉應用程序。這是正常的,通話結束,所以返回。
else: 一些 loginc 或服務器錯誤,需要記錄并修復
handler(c net.Conn){
defer c.Close()
for {
...
if e!=nil {
if e == io.EOF{
continue
}
if strings.Contains(e.Error(), "An existing connection was forcibly closed by the remote host.") {
return
}
log.Println(e.Error())
return
}
}
}
在你的情況下,你不想處理包含“使用關閉的網絡連接”的錯誤??梢院雎运⒂涀£P閉循環。否則一些內存會泄漏并且例程掛起。可能有一個隱藏的你忽略一遍又一遍地拋出的錯誤。

TA貢獻1772條經驗 獲得超6個贊
func recv(c *net.Conn) {
if c == nil {
return
}
input := bufio.NewScanner(*c)
for input.Scan() {
msg <- input.Text()
...
}
}
//main
conn, err := s.Accept()
c := &conn
...
go recv(&c)
for {
select {
case m := <-msg:
...
case <-timeout:
conn.Close()
c = nil
}
}
不確定這是否是最好的方法。當您關閉 conn 時,您可以將其設置為 nil,而不是從 nil conn 值中讀取。
- 3 回答
- 0 關注
- 204 瀏覽
添加回答
舉報