Reputation: 1253
I use an UDP socket on iOS. I experience a very strange behaviour when setting it to non-blocking mode and/or simulating a bad connection.
To set the socket in non-blocking mode with the usual fcntl
:
fcntl(socketfd, F_SETFL, O_NONBLOCK);
To simulate bad connection I use Network Link Conditioneer with 5/5 in/out packet loss and 50KBps out limit (which guarantees in my case that system out buffer will be full at some point).
I send data with sendto()
and I clock the call with clock()
and a printf()
.
Here is the data from my tests, data in ms:
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
I also notice that in case 2
there are many entries with 0 ms
, meaning that sendto()
has returned immediately, that explains the low average and standard deviation of the case.
At all occasions sendto()
returned a positive value corresponding to the number of bytes that were requested to be sent.
Now, there are several things I just can't understand:
sendto()
to return an error when it would block, instead from the data it seems that the call blocks until there is actually space to perform itThe behaviour seems inverted, with the exception that sendto
never reports a failure.
What am I doing wrong?
Socket creation:
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
}
Sending to:
sendto(socketfd, buffer, buffer_length, 0, (struct sockaddr *) &m_sRemoteHost, sizeof(m_sRemoteHost))
Upvotes: 0
Views: 345
Reputation: 1
How do you know your system's send buffer is getting full? You're just assuming that because you've rate-limited your connection, data backs up in the send buffer. It's more likely that it's getting dropped somewhere else. Since UDP makes no guarantees that any packet will be delivered, any piece of software or hardware anywhere on the packet's path is free to drop it at any time for any reason.
Per the 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.
Upvotes: 2