UDP 是 IPC 的可靠协议吗? [英] Is UDP a reliable protocol for IPC?

查看:19
本文介绍了UDP 是 IPC 的可靠协议吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.?

注意这是一个实践问题,而不是理论问题.如果答案因操作系统而异,请说明具体情况,尤其包括 Windows、Linux 和 Mac.

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 8.1 上丢弃了一个数据包(我得到 Received: 18432 (DROPPED PACKET)).
(我不确定为什么它不能在 Linux 上运行,但它应该接近工作了.)

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
", 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)
", v); return 3; }
            // else { fprintf(stderr, "Received: %lu
", v); }
            ++j;
        }
    }
}

推荐答案

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

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?

没有.即使所有通信都在同一主机上完成,UDP 数据包仍可能(有时会)被丢弃.

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

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

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).

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

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.

这篇关于UDP 是 IPC 的可靠协议吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆