如果具有MSG_PEEK的无阻塞recv成功,那么没有MSG_PEEK的后续recv也将成功吗?

问题描述 投票:12回答:5

这是我正在处理的一些代码的简化版:

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); / *错误...

sockets nonblocking recv
5个回答
9
投票

POSIX标准指定有关MSG_PEEK


5
投票

您还必须考虑可能在ret1和ret2之间调用不同线程上的不同recv调用的可能性。另一个调用将获取您的数据,从而使ret2最终没有任何数据,或者出乎意料地减少了数据。


2
投票

没有MSG_PEEK的第二次调用recv()可能因EINTR失败或返回不完整的数据,因为它已被信号中断。


1
投票

我不确定EAGAIN,但认为可以使用EBADF或ECONNRESET。


0
投票

对于您的简单情况,后续的recv将返回ret1字节数(如果ret1不是错误)。但是,对于多线程设计,可能并非总是如此。

© www.soinside.com 2019 - 2024. All rights reserved.