Reputation: 6479
I'm coding a networking application on Android.
I'm thinking of having a single UDP port and Datagram socket that receives all the datagrams that are sent to it and then have different processing queues for these messages.
I'm doubting if I should have a second or third UDP socket on standby. Some messages will be very short (100bytes or so), but others will have to transfer files.
My concern is, will the Android kernel drop the small messages if it's too busy handling the bigger ones?
Update "The latter function calls sock_queue_rcv_skb() (in sock.h), which queues the UDP packet on the socket's receive buffer. If no more space is left on the buffer, the packet is discarded. Filtering also is performed by this function, which calls sk_filter() just like TCP did. Finally, data_ready() is called, and UDP packet reception is completed."
Upvotes: 5
Views: 2889
Reputation: 84189
Let's get some basics down first:
Every socket has a receive and a send buffer. When network hardware signals the arrival of a new packet and the receive buffer is full, the packet is dropped. The buffer sizes are controlled via SO_RCVBUF
and SO_SNDBUF
socket options, see setsockopt(3)
. The OS sets some defaults (and there's the /etc/sysctl.conf
file). This is on a BSD system:
~$ sysctl -a|grep space net.inet.tcp.recvspace=16384 net.inet.tcp.sendspace=16384 net.inet.udp.recvspace=41600 net.inet.udp.sendspace=9216
The difference between TCP and UDP is that the former takes care of sequencing of data and retransmission of dropped packets, plus a flow control (slow reader slows down fast writer), while the latter doesn't.
So yes, using UDP to transfer files is not the best, but workable, option. One just have to reinvent a part of TCP and weigh that re-invention's overhead against the one of TCP. Then again, the general wisdom is that UDP is best suited for applications that can tolerate some packet reordering/loss (e.g. audio/video streams).
Then there's the mis-guided notion that every socket needs a separate thread for sending/receiving data, which is far from truth. Many excellent high-performance network applications have been written without threads, but using non-blocking sockets and some polling mechanism (see select(2)
, poll(2)
, epoll(7)
).
To the question itself:
Yes, the kernel might drop packets if the application is too busy to keep enough available space in sockets' receive buffers. But since each socket has its own, the separation of control and data streams would help. Personally though I would go for a simple TCP server setup - listen on a port, accept a connection per client, implement a meaningful protocol on top of a TCP stream. I agree that playing with UDP and low-level protocol state machines is a lot of fun, but it has been done already, and decades of research went into tuning TCP performance. What matters at the end of the day is reliability (first) and performance (second) of your application.
Hope this helps.
Upvotes: 8
Reputation: 1438
TCP's flow control will help you reduce dropped packets. Its fault tolerant and makes sure that packet will arrive in sequence.
Upvotes: 0
Reputation: 57902
UDP is a bad idea for transferring files, as you cannot guarantee the order in which packets will be received, or whether they will be received at all. If you are thinking to build a fault tolerant transport layer on top of this, you should just use TCP/IP instead, as that's exactly what it does.
UDP does not buffer or queue received packets. If a packet is received and you are waiting for data, you will receive it. If a packet is received while your program is busy doing some other processing, you won't get the packet at all. So if you receive two "simultaneous packets" (well, two very close together) there is a good chance you might miss one of them if you are doing any significant processing of each packet.
I don't see how having extra ports open will help you much. If you're busy processing a packet from port 1, then you'll miss any packets coming in on any other ports you're watching, unless each is running on a dedicated thread. You would be much better off copying the packet quickly into your own buffer and passing it on to another thread to process it, so your listener thread can get back to listening asap.
Upvotes: 1