Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is UDP a reliable protocol for IPC?

Tags:

sockets

udp

ipc

If I use UDP purely for inter-process communication (i.e., in 1 system, with no network involved), can I consider it to be reliable? Or do I still need to worry about packets getting dropped, etc.?

Note that this is a practical question, not a theoretical one. If the answer differs across OSes, please explain how, in particular including Windows, Linux, and Mac.


Edit: Nope, it's not reliable -- example below.

Thanks to the current answer for pointing me in the right direction.
This code drops a packet on Windows 8.1 (I get Received: 18432 (DROPPED PACKET)).
(I'm not sure why it doesn't run on Linux, but it should be close to working.)

#include <stdio.h>
#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#endif

int main()
{
#ifdef _WIN32
    typedef int socklen_t;
#else
    typedef int SOCKET;
#endif
    SOCKET r = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in addr = { AF_INET };
    addr.sin_addr.s_addr = htonl(0x7F000001);
    {
        socklen_t addrlen = sizeof(addr);
        if (bind(r, (struct sockaddr *)(&addr), addrlen) == -1 ||
            getsockname(r, (struct sockaddr *)(&addr), &addrlen) == -1)
        {
            return 1;
        }
    }
    SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
    int tids = 0;
    for (long c = 0, i = 0, j = 0; c < 1000000; ++c)
    {
        if ((c + 1) % 10)
        {
            int n = sendto(s, (char const *)(&i), sizeof(i), 0, (struct sockaddr const *)(&addr), sizeof(addr));
            if (n != sizeof(i)) { return 1; }
            // else { fprintf(stderr, "Sent:     %lu\n", i); }
            ++i;
        }
        else
        {
            struct sockaddr temp;
            socklen_t templen = sizeof(temp);
            long v;
            int n = recvfrom(r, (char *)(&v), sizeof(v), 0, (struct sockaddr *)(&temp), &templen);
            if (n != sizeof(v)) { return 2; }
            else if (v != j) { fprintf(stderr, "Received: %lu (DROPPED PACKET)\n", v); return 3; }
            // else { fprintf(stderr, "Received: %lu\n", v); }
            ++j;
        }
    }
}
like image 724
user541686 Avatar asked Dec 19 '22 13:12

user541686


1 Answers

If I use UDP purely for inter-process communication (i.e., in 1 system, with no network involved), can I consider it to be reliable?

No. UDP packets can (and sometimes will) still be dropped even when all communication is being done over the same host.

You can demonstrate this for yourself, if you want; set up two UDP-socket-using programs on the same host, with program A sending UDP packets to program B that receives them and records them. (Include sequence numbers in the UDP packets so that program B can easily tell when a packet was not received).

Once that is working and packets are being transmitted at a decent rate, put some code into program B so that every so often it calls sleep(5) (or similar, so that program B fails to call recv() on its UDP socket for a significant amount of time). You'll likely see that after the sleep() call returns, program B reports that some packets were skipped -- because while B was asleep, the incoming-packets buffer for its UDP socket became full and then some packets were dropped by the networking stack because there was no place to put them.

like image 115
Jeremy Friesner Avatar answered Jan 05 '23 15:01

Jeremy Friesner