[英]sendto() incoherent behaviour on UDP socket
我在iOS上使用UDP套接字。 将其设置为非阻止模式和/或模拟不良连接时,我会遇到一个非常奇怪的行为。
要使用通常的fcntl
将套接字设置为非阻塞模式:
fcntl(socketfd, F_SETFL, O_NONBLOCK);
为了模拟不良连接,我使用5/5输入/输出数据包丢失和50KBps输出限制的Network Link Conditionerer(在我的情况下,这保证了系统输出缓冲区在某个时候会变满)。
我使用sendto()
发送数据,并使用clock()
和printf()
为调用clock()
。
这是我的测试数据,以毫秒为单位:
min 0
/ max 929
/ avg 226
/ std 111
min 0
/ max 611
/ avg 38
/ std 84
min 0
/ max 6244
/ avg 601
/ std 1071
min 0
/ max 5774
/ avg 400
/ std 747
我还注意到,在情况2
,有许多条目具有0 ms
,这意味着sendto()
立即返回了,这解释了该情况的低平均值和标准偏差。
在任何情况下, sendto()
返回一个正值,该值与请求发送的字节数相对应。
现在,有几件事我无法理解:
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无法保证将传送任何数据包,因此,由于任何原因,数据包路径上任何位置的任何软件或硬件都可以随时随意丢弃。
根据Wikipedia上的UDP页面 :
UDP是RFC 768中记录的最小的面向消息的传输层协议。UDP 不保证上层协议进行消息传递 ,并且UDP层一旦发送便不保留UDP消息的状态。 因此,UDP有时被称为不可靠数据报协议。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.