UDP是IPC的可靠协议吗?

Meh*_*dad 3 sockets udp ipc

如果我纯粹使用UDP进行进程间通信(即,在1个系统中,不涉及网络),我可以认为它是可靠的吗?或者我仍然需要担心丢包等问题?

请注意,这是一个实际问题,而不是理论问题.如果操作系统的答案不同,请解释如何,特别是包括Windows,Linux和Mac.


编辑:不,这不可靠 - 例如下面.

感谢目前的答案,指出我正确的方向.
此代码在Windows 8.1上删除了一个数据包(我得到Received: 18432 (DROPPED PACKET)).
(我不确定它为什么不在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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jer*_*ner 9

如果我纯粹使用UDP进行进程间通信(即,在1个系统中,不涉及网络),我可以认为它是可靠的吗?

不可以.即使在同一主机上进行所有通信,UDP数据包仍然可以(有时会)丢弃.

如果你愿意,你可以自己演示这个; 在同一主机上设置两个使用UDP套接字的程序,程序A向程序B发送UDP数据包,接收它们并记录它们.(在UDP数据包中包含序列号,以便程序B可以轻松判断何时未收到数据包).

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

  • 他们都是.你不需要观察 (2认同)
  • @Mehrdad你会在任何操作系统下看到它。这是 RAM 空间有限这一事实的自然结果,因此一次只能存储有限数量的 UDP 数据包(等待接收应用程序处理)。 (2认同)