这是我正在处理的一些代码的简化版:
void
stuff(int fd)
{
int ret1, ret2;
char buffer[32];
ret1 = recv(fd, buffer, 32, MSG_PEEK | MSG_DONTWAIT);
/* Error handling -- and EAGAIN handling -- would go here. Bail if
necessary. Otherwise, keep going. */
/* Can this call to recv fail, setting errno to EAGAIN? */
ret2 = recv(fd, buffer, ret1, 0);
}
如果我们假设对recv的第一次调用成功,返回一个介于1到32之间的值,那么可以安全地假设第二个调用也将成功吗? ret2可以小于ret1吗?在哪种情况下?
((为清楚起见,假设在第二次调用recv期间没有其他错误情况:没有信号传递,它不会设置ENOMEM,等等。还假设没有其他线程会看fd。] >
我在Linux上,但我相信MSG_DONTWAIT是这里唯一的Linux专用东西。假设先前在其他平台上设置了正确的fnctl。)
这是我正在处理的某些代码的简化版本:void stuff(int fd){int ret1,ret2;字符缓冲区[32]; ret1 = recv(fd,buffer,32,MSG_PEEK | MSG_DONTWAIT); / *错误...
POSIX标准指定有关MSG_PEEK
:
您还必须考虑可能在ret1和ret2之间调用不同线程上的不同recv调用的可能性。另一个调用将获取您的数据,从而使ret2最终没有任何数据,或者出乎意料地减少了数据。
没有MSG_PEEK的第二次调用recv()可能因EINTR失败或返回不完整的数据,因为它已被信号中断。
我不确定EAGAIN,但认为可以使用EBADF或ECONNRESET。
对于您的简单情况,后续的recv将返回ret1字节数(如果ret1不是错误)。但是,对于多线程设计,可能并非总是如此。