結論
首先,先定義下我的理解,當在Read時,收到一個IO.EOF,代表的就是對端已經關閉了發送的通道,通常來說是發起了FIN。
那么根據自己的實際業務,就可以進行判斷,這里的IO.EOF到底該怎么利用,比如說判定為作業結束,直接關閉連接,停止業務。或者等待服務端發送完數據再停止業務都是可以的。
GO中IO.EOF的定義
// EOF is the error returned by Read when no more input is available.
// Functions should return EOF only to signal a graceful end of input.
// If the EOF occurs unexpectedly in a structured data stream,
// the appropriate error is either ErrUnexpectedEOF or some other error
// giving more detail.
var EOF = errors.New("EOF")
核心意思就一句,收到這個就代表輸入方已經正常結束了。
然后,在看Read方法
// Read implements the Conn Read method.
func (c *conn) Read(b []byte) (int, error) {
if !c.ok() {
return 0, syscall.EINVAL
}
n, err := c.fd.Read(b)
if err != nil && err != io.EOF {
err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
}
return n, err
}
最后的一個if,將io.EOF獨立出來了。
分析
首先TCP是全雙工的,並且每次關閉的時候,都會發起4次揮手。參考下圖
當客戶端發起FIN之后,服務器會進如CLOSE_WAIT的狀態,這個狀態的主要意義在於,如果服務器有沒有發送完的數據需要發送給客戶端時,那么需要繼續發送,當服務器端發送完畢之后,再給客戶端回復FIN表示關閉。
所以,咱們可以間接的認為,當我們收到一個IO.EOF的時候,就是客戶端在發起FIN了。
首發於:zfcode.com