简体   繁体   English

UDP是IPC的可靠协议吗?

[英]Is UDP a reliable protocol for IPC?

If I use UDP purely for inter-process communication (ie, in 1 system, with no network involved ), can I consider it to be reliable? 如果我纯粹使用UDP进行进程间通信(即,在1个系统中, 不涉及网络 ),我可以认为它是可靠的吗? 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. 如果操作系统的答案不同,请解释如何,特别是包括Windows,Linux和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) ). 此代码在Windows 8.1上丢弃一个数据包(我Received: 18432 (DROPPED PACKET) )。
(I'm not sure why it doesn't run on Linux, but it should be close to working.) (我不确定它为什么不在Linux上运行,但它应该接近工作。)

#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;
        }
    }
}

If I use UDP purely for inter-process communication (ie, in 1 system, with no network involved), can I consider it to be reliable? 如果我纯粹使用UDP进行进程间通信(即,在1个系统中,不涉及网络),我可以认为它是可靠的吗?

No. UDP packets can (and sometimes will) still be dropped even when all communication is being done over the same host. 不可以。即使在同一主机上进行所有通信,UDP数据包仍然可以(有时会)丢弃。

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. 在同一主机上设置两个使用UDP套接字的程序,程序A向程序B发送UDP数据包,接收它们并记录它们。 (Include sequence numbers in the UDP packets so that program B can easily tell when a packet was not received). (在UDP数据包中包含序列号,以便程序B可以轻松判断何时未收到数据包)。

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). 一旦它工作并且数据包以合适的速率传输,将一些代码放入程序B,以便每隔一段时间调用sleep(5)(或类似的,以便程序B无法在其UDP套接字上调用recv()很长一段时间)。 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. 您可能会看到,在sleep()调用返回后,程序B报告某些数据包被跳过 - 因为当B处于睡眠状态时,其UDP套接字的传入数据包缓冲区已满,然后网络中的某些数据包被丢弃堆叠,因为没有地方放他们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM