Socket recv()函数 在C++中,在Windows操作系统上,在TCP套接字的调用(RevVor)调用中,如果套接字连接被某种方式关闭,ReCVE()将立即返回,或者它会挂起?

Socket recv()函数 在C++中,在Windows操作系统上,在TCP套接字的调用(RevVor)调用中,如果套接字连接被某种方式关闭,ReCVE()将立即返回,或者它会挂起?,c++,winsock,winsock2,C++,Winsock,Winsock2,阻塞和非阻塞套接字中会出现什么结果(立即返回或挂起)? 我使用的是套接字版本2 提前感谢。如果您的recv()是基于BSD的-几乎所有的BSD都是基于BSD的-如果连接关闭,它将立即返回(根据本地端的状态),无论套接字是阻塞的还是非阻塞的。根据连接是如何关闭的,在非正常情况下,它应该或多或少立即返回值socket\u ERROR,并将WSAGetLastError设置为可能的原因之一,如WSAENOTCONN,或者只返回0在正常连接关闭场景中。阻塞和非阻塞套接字之间的情况相同 如果套接字是面向连

阻塞和非阻塞套接字中会出现什么结果(立即返回或挂起)? 我使用的是套接字版本2

提前感谢。

如果您的
recv()
是基于BSD的-几乎所有的BSD都是基于BSD的-如果连接关闭,它将立即返回(根据本地端的状态),无论套接字是阻塞的还是非阻塞的。

根据连接是如何关闭的,在非正常情况下,它应该或多或少立即返回值
socket\u ERROR
,并将
WSAGetLastError
设置为可能的原因之一,如
WSAENOTCONN
,或者只返回
0
在正常连接关闭场景中。阻塞和非阻塞套接字之间的情况相同

如果套接字是面向连接的,并且远程端已正常关闭连接,并且已接收到所有数据,则recv将立即完成,并接收到零字节。如果连接已重置,recv将失败,错误为WSAECONNRESET

但是,因为我知道Windows API并不总是像文档中描述的那样工作,所以我建议对其进行测试。

recv()
在正常断开连接时将返回0,即对等方关闭其连接结束,其套接字堆栈向套接字堆栈发送了一个
FIN
数据包。无论您使用的是阻塞套接字还是非阻塞套接字,都可以保证立即得到这个结果

recv()
在任何其他错误(包括异常连接丢失)时将返回-1。 您需要使用
WSAGetLastError()
了解实际发生的情况。对于阻塞套接字上的断开连接,通常会收到错误代码,例如
WSAECONNRESET
WSAECONNABORTED
。对于非阻塞套接字上的断开连接,
recv()
可能会立即报告
WSAEWOULDBLOCK
错误,然后在稍后某个时间报告实际错误,可能通过
select()
和异常
fd_set
或异步通知,取决于如何实现非阻塞逻辑

但是,无论哪种方式,您都不能保证在连接丢失时及时获得故障结果!在操作系统认为连接实际丢失并使套接字连接无效之前,可能需要一些时间(秒、分钟,在极少数情况下甚至可能是小时)。TCP被设计为在可能的情况下恢复丢失的连接,因此它必须考虑临时网络中断等,因此存在内部超时。在代码中看不到这一点,它发生在后台


如果您不想等待操作系统内部超时,您可以始终在代码中使用自己的超时,例如通过
select()
setsocktop(SO\u RCVTIMEO)
,TCP保持有效(
setsockopt(SO\u KEEPALIVE)
WSAIoCtl(SIO\u KEEPALIVE\u VALS)
)等。您可能仍然不会立即出现故障,但是,在标准C++中没有<代码> ReVE()/Cuffe >,所以在你指定使用的网络API之前,你的问题将是不完整的,对其他人没有帮助。如果连接没有关闭,而是挂在另一边,它是一个阻塞插座,它会挂断。(虽然这有点超出了问题的范围)。@SimonDoppler:所有这些电话都是从当地的角度出发的/当然,当地的状态会延迟反映另一端刚刚发生的事情,而且可能会很长。