jas*_*ogd 8 c python sockets network-programming
为什么在recv收到所有数据之前系统调用只是阻塞?每当我看到一个recv呼叫时,它就会在一个while循环中继续呼叫,recv直到所有数据都存在.为什么不recv首先阻止?
您可以请求recv块,直到收到所有数据,并带有MSG_WAITALL标志.但是,如果信号到达,则执行某些工作(即接收部分数据)的系统调用无法自动重新启动以接收其余信号.因此,即使有MSG_WAITALL,也可能在缓冲区已满之前可能会返回recv调用,并且您必须准备好处理这些情况.鉴于此,许多人只是选择循环,而不是打扰鲜为人知的标志,如MSG_WAITALL.
至于为什么默认情况是这样的,有几个原因可以想到:
telnet协议,这在BSD套接字API设计时很流行.你通常会在同一时间内接收的字节屈指可数,没有长度字段告诉你多少数据的期望,而且你需要显示的数据的时候了.在此处填充缓冲区之前阻塞是没有意义的.与使用SMTP或IMAP等面向行的协议一样,在收到所有命令之前,您不知道命令的持续时间.recv通常用于数据报套接字,它接收单个数据报,即使它比提供的缓冲区小得多.流式套接字的自然扩展是尽可能多地返回,而无需等待.但最重要的,因为你需要做好准备,以应对部分缓冲无论如何,这是很好的,迫使人们在默认情况下处理它,所以他们转起来的错误在他们的循环早期-而不是让他们仍然隐藏,直到信号到了一个不幸的时刻.