首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用MSG_NONBLOCK和MSG_WAITALL的recv

使用MSG_NONBLOCK和MSG_WAITALL的recv
EN

Stack Overflow用户
提问于 2010-05-31 12:13:57
回答 3查看 22.6K关注 0票数 11

我想使用带有非阻塞标志的recv syscall MSG_NONBLOCK。但是有了这个标志,syscall可以在完全满足请求之前返回。所以,

  • 我可以添加MSG_WAITALL标志吗?是nonblocking?
  • or吗?如何用非阻塞的recv

将阻塞recv重写到循环中?

EN

回答 3

Stack Overflow用户

发布于 2013-06-11 15:23:12

至少对于Linux上的IPv4 TCP来说,如果指定了MSG_NONBLOCK (或者文件描述符设置为非阻塞),那么MSG_NONBLOCK就会被忽略。

来自Linux内核中net/ipv4 4/tcp.c中的tcp_recvmsg():

代码语言:javascript
复制
if (copied >= target && !sk->sk_backlog.tail)
        break;

if (copied) {
        if (sk->sk_err ||
            sk->sk_state == TCP_CLOSE ||
            (sk->sk_shutdown & RCV_SHUTDOWN) ||
            !timeo ||
            signal_pending(current))
                break;

如果指定了MSG_DONTWAIT,则此强制转换中的目标设置为所请求的大小,如果没有指定,则设置一些较小的值(至少1)。该功能将在下列情况下完成:

已经复制了足够多的字节,有一个套接字错误的non-blocking)

  • There's

  • ,套接字已经关闭或关机

  • 时间为0(套接字设置为

  • ,一个信号挂起的进程

G 212)

在我看来,这似乎是Linux中的一个bug,但无论是哪种方式,它都无法按您所希望的方式工作。看起来,dec- It 100的解决方案是可以的,但是如果您尝试在多个进程或线程中从同一个套接字接收,则存在一个争用条件。

也就是说,在线程执行了peek之后,另一个线程/进程可能会调用另一个recv(),从而导致线程阻塞第二个recv()。

票数 5
EN

Stack Overflow用户

发布于 2010-05-31 12:59:24

编辑:

平原recv()将在调用时返回tcp缓冲区中的任何内容,最多返回所请求的字节数。如果没有任何数据可以在套接字上读取,MSG_DONTWAIT就可以避免阻塞。MSG_WAITALL请求阻塞,直到可以读取所请求的全部字节。这样你就不会有“全部或没有”的行为。充其量,您应该获得EAGAIN,如果没有数据,并阻塞,直到完整的消息是可用的,否则。

您可能可以使用FIONREAD (如果您的系统支持的话)在MSG_PEEK或ioctl()中设计一些可以有效地按照您的需要运行的东西,但我不知道如何使用recv()标志来实现您的目标。

票数 3
EN

Stack Overflow用户

发布于 2011-06-07 21:10:30

这就是我对同样的问题所做的,但我想确认一下,这件事和预期的一样.

代码语言:javascript
复制
ssize_t recv_allOrNothing(int socket_id, void *buffer, size_t buffer_len, bool block = false)
{
    if(!block)
    {
        ssize_t bytes_received = recv(socket_id, buffer, buffer_len, MSG_DONTWAIT | MSG_PEEK);

        if (bytes_received == -1)
            return -1;

        if ((size_t)bytes_received != buffer_len)
            return 0;
    }

    return recv(socket_id, buffer, buffer_len, MSG_WAITALL);
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2943434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档