Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果插座仍然连接,EndReceive是否应该返回零?_C#_Sockets_Asynchronous - Fatal编程技术网

C# 如果插座仍然连接,EndReceive是否应该返回零?

C# 如果插座仍然连接,EndReceive是否应该返回零?,c#,sockets,asynchronous,C#,Sockets,Asynchronous,我正在插座上进行以下BeginReceive调用: 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

我正在插座上进行以下BeginReceive调用:

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可以返回零?

Socket.EndReceive()
在一种特定情况下返回0:远程主机已开始或确认正常的关闭序列(例如,对于基于.NET
Socket的程序,调用
Socket.Shutdown()
使用
SocketShutdown.Send
SocketShutdown.两者都使用

但是请注意,从技术上讲,在插座最终关闭之前,它是“连接”的


您不应使用
Connected
属性来确定是否从套接字发出另一次读取。相反,由于返回值0是专门保留的,表示不再发送数据,因此您只需检查
EndReceive()
的返回值,如果该值为正数(即不是零),则再次调用
BeginReceive()

有时我们正在测试TCP连接,忘记初始化缓冲区数组。当它为null或为空时,EndReceive()将始终返回0。我在这方面有一次愚蠢的经历。

看看这个。似乎除了3种情况外,它还将返回0。Levi,我已经看到了那篇文章。这和我要问的问题没什么关系。我特别询问EndReceive的返回值,以及返回值为零是否意味着套接字上不再有任何可用数据。谢谢。我在想,如果套接字没有从另一端正确关闭,那么“socket.Connected”可能不是再次调用BeginReceive的有效检查。事实上,如果服务器断开连接,连接有时可能会被卡住,但客户端不承认。我想这取决于您对“卡住”的定义。如果客户端未能确认关闭,但仍然关闭其端,或只是在未清理的情况下退出进程,则服务器仍将看到调用的完成回调,但当调用
EndReceive()
时,将出现异常(指示连接已重设),而不是0返回值。无论如何,服务器最终会发现套接字不再连接。:)我没有在EndReceive上得到异常,我只是得到一个返回值零,我假设零并不一定意味着有错误。您认为如果EndReceive返回零,客户端应该关闭ReceiveCallback中的套接字吗?返回值0表示另一端称为shutdown。每一端在发送完数据后都应该关闭套接字(而不是关闭)。每一端,一旦他们已经关闭了套接字,并且有一个0字节的接收完成(在他们关闭端之前或之后),那么他们就可以关闭套接字。这取决于你还有什么要做。如果您自己已经完成了数据发送,因此已经调用了
Shutdown(SocketShutdown.Send)
,那么您将在该点关闭套接字。如果您仍然有数据要发送,那么您只需注意某个地方(例如,连接状态中存储的私有标志…在许多情况下,您已经在维护某种连接状态),远程主机已经关闭,然后当您完成发送时,您调用
shutdown(SocketShutdown.Both)
,然后关闭套接字。