c++ - 为 posix recv 设置超时会导致丢失 udp 数据包吗?

标签 c++ sockets posix

我找到了 this answer关于如何为 posix 套接字设置超时。该答案的 Linux 部分:

// LINUX
struct timeval tv;
tv.tv_sec = timeout_in_seconds;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);

以及来自 posix 文档的引述:

SO_RCVTIMEO

Sets the timeout value that specifies the maximum amount of time an input function waits until it completes. It accepts a timeval structure with the number of seconds and microseconds specifying the limit on how long to wait for an input operation to complete. If a receive operation has blocked for this much time without receiving additional data, it shall return with a partial count or errno set to [EAGAIN] or [EWOULDBLOCK] if no data is received. The default for this option is zero, which indicates that a receive operation shall not time out. This option takes a timeval structure. Note that not all implementations allow this option to be set.

我不明白的是:这会导致丢失 udp 包吗? 如果在接收 udp 包时达到超时怎么办?

还相关:setting timeout for recv fcn of a UDP socket

PS:我知道UDP本质上是不可靠的,所以我的问题实际上主要是关于处理udp消息时发生超时的情况。

最佳答案

没有;它不会让您更有可能丢包。

查看网络传输如何在较低级别发生;你有网卡。当此卡接收数据时,无论您的程序在做什么,它都会将数据存储到自己的内存区域中。当你调用 recv;您要求操作系统将数据从网卡内存移动到您的程序内存。这意味着如果您的线程正在做其他事情时有一个数据包进来;它不仅会被丢弃,还会在您的线程下次获取数据时进行处理。

如果您的线程没有足够频繁地调用 recv;那么网卡的内存就会变满。发生这种情况时,无法存储新数据包;如果它使用 TCP,那么路由器将被告知它无法处理它;如果它是 UDP,那么它将被简单地丢弃。正是这一部分使 UDP 本质上不可靠,因为它可能在数据包传输过程中的任何时候发生。

超时会影响线程等待数据出现在网卡内存区域的时间;除非你再也不调用 recv;不影响丢弃的数据包。

关于c++ - 为 posix recv 设置超时会导致丢失 udp 数据包吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49775673/

相关文章:

c - 使用文件描述符而不是文件指针的 getline()

c++ - 我的表情符号程序在C++中显示带有问号的框

c++ - 使用多线程的硬盘争用

主机名的 Python 套接字替换变量

c - Perl:阻塞信号没有延迟 -> 提供了测试代码

linux - 同一个文件的两个文件描述符

c++ - 在 Boost (C++) 中没有类跟踪的派生类序列化

python - 在 Cython 中将 C++ vector 转换为 numpy 数组而无需复制

java - Java中父子线程的通信

sockets - Haskell 数据报 UDP 套接字 : Receiving works but sending doesn't