ios - UDP 套接字上的 sendto() 不连贯行为

标签 ios c sockets

我在 iOS 上使用 UDP 套接字。将其设置为非阻塞模式和/或模拟不良连接时,我遇到了一种非常奇怪的行为。

使用通常的fcntl将套接字设置为非阻塞模式:

fcntl(socketfd, F_SETFL, O_NONBLOCK);

为了模拟不良连接,我使用具有 5/5 输入/输出数据包丢失和 50KBps 输出限制的 Network Link Conditioneer(这保证在我的情况下系统输出缓冲区将在某个时候满)。

我使用 sendto() 发送数据,并使用 clock()printf() 为调用计时。


这是我的测试数据,以毫秒为单位:

  1. 阻塞,连接良好:min 0/max 929/avg 226/std 111
  2. 阻塞,连接不良:min 0/max 611/avg 38/std 84
  3. 非阻塞,连接良好:min 0/max 6244/avg 601/std 1071<
  4. 非阻塞,连接不良:min 0/max 5774/avg 400/std 747<

我还注意到,在 2 的情况下,有许多 0 ms 的条目,这意味着 sendto() 已立即返回,这解释了个案的低平均值和标准偏差。

在所有情况下,sendto() 都会返回一个与请求发送的字节数相对应的正值。

现在,有几件事我无法理解:

  1. 在阻塞模式下,我希望它一直阻塞直到有可用的系统缓冲区来存储数据,但似乎数据被丢弃了(因为调用会立即返回)
  2. 在非阻塞模式下,我希望 sendto() 在它阻塞时返回一个错误,而不是从数据看来调用阻塞直到实际有空间来执行它<

除了 sendto 从不报告失败之外,行为似乎是颠倒的。

我做错了什么?


套接字创建:

int socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
// error checks
setsockopt(socketfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));

int tos = 0xB8; // VOICE
setsockopt(socketfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));

int rc = fcntl(m_iSocket, F_SETFL, O_NONBLOCK);
if (rc != 0) {
    // error of fcntl is notified
}

发送至:

sendto(socketfd, buffer, buffer_length, 0, (struct sockaddr *) &m_sRemoteHost, sizeof(m_sRemoteHost))

最佳答案

您如何知道系统的发送缓冲区已满?您只是假设因为您对连接进行了速率限制,所以数据会备份到发送缓冲区中。它更有可能被丢弃在其他地方。由于 UDP 不保证任何数据包都会被传送,因此数据包路径上任何地方的任何软件或硬件都可以随时出于任何原因随意丢弃它。

根据 UDP page on Wikipedia :

UDP is a minimal message-oriented transport layer protocol that is documented in RFC 768. UDP provides no guarantees to the upper layer protocol for message delivery and the UDP layer retains no state of UDP messages once sent. For this reason, UDP sometimes is referred to as Unreliable Datagram Protocol.

关于ios - UDP 套接字上的 sendto() 不连贯行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41344462/

相关文章:

c - 部分提交黑客排名

c - 关于 SSL_do_handshake 阻塞调用

ios - 快速套接字 io 连接到服务器,但管理器和引擎正在释放

ios - 检测何时无法正确显示 unicode 字符

ios - 设置 map 的默认起始位置 - iOS

ios - 动态更改表格 View 单元格的高度

python - 无法连接到Python服务器

ios - iOS Per-App VPN 是否需要 MDM

C 封装使用 const 指针指向 const 数据

java - 来自 Java UDP 的空指针异常