I'm trying to read udp packets using recv
non-blocking mode in a loop as shown below, however the call always return EAGAIN
, but tcpdump shows that 0 packets dropped by kernel
, what could be the cause of EAGAIN
?
for (;;)
{
const auto rc = ::recv(fd, data, maxSize, MSG_TRUNC);
if (rc < 0)
{
switch (errno)
{
case (EINTR):
break;
case (EAGAIN):
spdlog::error("EAGAIN");
...
}
}
else if (rc == 0)
{
throw std::runtime_error("Connection closed");
}
}
tcpdump ctrl C return:
668 packets captured
981 packets received by filter
0 packets dropped by kernel
CodePudding user response:
0 packets dropped by kernel just means that the packet capture mechanism in the kernel did not drop any packets. It has nothing to do with the receiving socket.
Note also that tcpdump captures packets before they are processed by the firewall, so it might well be that they get blocked by the firewall and never received on the socket even if tcpdump can capture these.
Also, calling recv
in a busy loop will likely return EAGAIN
most of the time since most of the time no data are available on the socket. Non-blocking sockets are usually used together with something which detects socket activity and blocks if there is no activity, i.e. select
, poll
, kqueue
, ... . Combining these mechanisms allows to deal with many sockets in a single thread. Using a busy loop on a single socket instead almost never makes sense.
CodePudding user response:
It's all because of docker host network doesn't work with OSX, so my application running insider the container cannot receive the UDP packets sending from the host.