2014-11-04 379 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

相关问题