2014-11-04 158 views
3

我正在做一個插座上以下BeginReceive電話:如果套接字仍然連接,EndReceive是否會返回零?

m_socket.BeginReceive(m_buffer, 0, m_buffer.Length, SocketFlags.Partial, this.ReceiveCallback, null); 
在我的課

ReceiveCallback功能我叫

try { 
    int bytesReadFromSocket = m_socket.EndReceive(ar); 
    if(bytesReadFromSocket > 0) { 
     // Do some processing 
    } 
} 
finally { 
    if(m_socket.Connected) m_socket.BeginReceive(m_buffer, 0, m_buffer.Length, SocketFlags.Partial, this.ReceiveCallback, null); 
} 

我遇到的問題是,EndReceive將返回零,但m_socket .Connected返回true,所以我再次調用BeginReceive。這發生在一個永不停止的緊密循環中。當EndReceive返回零時,從文檔中不清楚。我認爲它只發生在套接字關閉時,但這似乎不是真的。

所以問題仍然存在,在什麼情況下EndReceive可以返回零?

+0

檢查了這一點。 http://stackoverflow.com/questions/3970825/when-does-endreceive-return-zero-bytes 看來除了3種情況之外,它會返回0. – 2014-11-04 17:05:13

+0

列維,我已經看到了那篇文章。這與我所問的問題並無關係。我具體詢問EndReceive的返回值,如果返回值爲零意味着套接字上不會有更多數據可用。 – bpeikes 2014-11-04 18:08:03

回答

3

Socket.EndReceive()返回0在一個具體情況下:遠程主機已開始或承認優美閉合序列(例如,對於一個.NET Socket基於程序,調用與Socket.Shutdown()要麼SocketShutdown.SendSocketShutdown.Both)。

但是請注意,從技術上講,直到套接字最終關閉,它才「連接」。

您不應使用Connected屬性來確定是否從套接字發出另一個讀取。相反,由於返回值0專門用於指示不再發送數據,因此只要檢查返回值EndReceive()並再次調用BeginReceive()(如果該值爲正數(即非零))。

+0

謝謝。我在想,如果套接字沒有從另一端正確關閉,那麼「Socket.Connected」可能不是再次調用BeginReceive的有效檢查。事實上,聽起來像是如果服務器斷開連接,連接可能會卡住,但客戶端不會承認它。 – bpeikes 2014-11-04 18:10:48

+0

我想這取決於你的「卡住」的定義。如果客戶端無法確認關閉,但仍然關閉它的結束,或者只是退出進程而不清理,那麼服務器仍然會看到調用完成回調,但是當你調用EndReceive()時,你會得到一個異常(表示連接已重置)而不是0返回值。不管怎樣,服務器最終都會知道套接字不再連接。 :) – 2014-11-04 18:14:01

+0

我沒有在EndReceive上得到異常,我只是得到一個零值返回值,並且我認爲零不一定意味着有錯誤。你會說如果EndReceive返回零,客戶端應該關閉ReceiveCallback中的套接字? – bpeikes 2014-11-04 18:17:28

相關問題