【问题标题】:Using non-blocking socket. errno is always EAGAIN after calling recvfrom使用非阻塞套接字。调用 recvfrom 后,errno 总是 EAGAIN
【发布时间】:2012-11-29 18:26:36
【问题描述】:

我正在将我的网络代码从 Windows 移植到 Linux,但并非没有问题。 出于某种原因,当我将套接字设置为非阻塞时,recvfrom 将无法正常工作。你看,在我调用 recvfrom 之后,errno 总是 EAGAIN,不管我收到多少数据包,它总是 EAGAIN。如果我注释掉将套接字设置为无阻塞的代码,则代码运行良好。那么它正在工作,但它正在阻塞......

这是我用来将套接字设置为非阻塞的代码:

int nonBlocking = 1;
if ( fcntl( handle, F_SETFL, O_NONBLOCK, nonBlocking ) == -1 )
{
    std::cout << "failed to set non-blocking socket" << std::endl;
    return false;
}

关于我做错了什么有什么想法吗? (它在我的 Windows 版本中运行良好:

DWORD nonBlocking = 1;
ioctlsocket( handle, FIONBIO, &nonBlocking );

【问题讨论】:

  • 我从每个循环中调用 recv。这就是为什么我需要它是非阻塞的。但是现在它并没有阻止我的应用程序做其他事情,而是忽略/阻止我的传入数据包?
  • 您是说当您不将套接字设置为非阻塞时您可以完美地读取和处理数据包?无论如何,在没有数据包的情况下获得EAGAIN是正常的。你怎么知道它不应该在任何给定时间返回 EAGAIN ?
  • 我在问你,会吗? if errno == to EAGAIN 丢包是不是错了?
  • 我不确定你在说什么,EAGAIN 表示现在没有数据包。这就是将套接字设置为非阻塞的作用,它将使recv/read/recvfrom/等。如果现在没有数据,则返回 EAGAIN,而不是阻塞直到有东西到达。

标签: c++ linux sockets udp


【解决方案1】:

首先,在检查errno的值之前,你应该检查recvfrom()的返回值。

如果它返回-1,那么errno 值将有意义。

来自recvfrom手册页:

如果套接字上没有可用的消息,则接收调用等待 为了 要到达的消息,除非套接字是非阻塞的(参见 fcntl(2)), 在这种情况下,返回值 -1 并且外部变量 errno 设置为 EAGAIN。

简而言之:

在你打电话给recvfrom的那一刻,没有什么要读的

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 2014-02-03
    • 1970-01-01
    • 2016-07-15
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多