gpt4 book ai didi

sockets - IP 组播 + UDP : Should I receive data for all groups?

转载 作者:行者123 更新时间:2023-12-03 19:44:50 25 4
gpt4 key购买 nike

IP Multicast over UDP 的正确行为是什么?

想象一下自己以下场景:

  • 我们尝试通过 UDP 与 IP 协议(protocol)通信。
  • 我们打开一个带有特定端口的 UDP 套接字(例如 60001)
  • 然后我们将套接字加入某个多播组(例如 239.192.0.1)
  • 我们打开另一个端口为 60002
  • 的 UDP 套接字
  • 然后我们将套接字加入其他多播组(例如 239.192.0.2)

  • 当它在 Windows 中使用 Winsock 完成时,每个套接字只有在满足两个条件时才成为数据:
  • UDP 端口匹配
  • 和多播组匹配。

  • 这是一些德尔福代码:
    procedure Connect();
    var err: Integer;
    wData: WsaData;
    reuse: Integer;
    begin
    FillChar(wData, SizeOf(wData), 0);
    err := WSAStartup(MAKEWORD(2, 2), wData);
    if err = SOCKET_ERROR then Exit;

    _fd := socket(AF_INET, SOCK_DGRAM, 0);
    if _fd = INVALID_SOCKET then Exit;

    reuse := 1;
    if (setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, Pointer(@reuse), SizeOf(reuse)) < 0) then Exit;

    FillChar(_addr, sizeof(_addr), 0);
    _addr.sin_family := AF_INET;
    if (_listeningInterface = '0.0.0.0') or not _isIpAddress(_listeningInterface) then
    _addr.sin_addr.s_addr := htonl(INADDR_ANY)
    else
    _addr.sin_addr.s_addr := inet_addr(PAnsiChar(_listeningInterface));
    _addr.sin_port := htons(_port);

    if (bind(_fd, _addr, sizeof(_addr)) < 0) then Exit;

    if _isMulticast() then begin
    _mreq.imr_multiaddr.s_addr := inet_addr(PAnsiChar(_multicastGroup));
    if (_listeningInterface = '0.0.0.0') or not _isIpAddress(_listeningInterface) then
    _mreq.imr_interface.s_addr := htonl(INADDR_ANY)
    else
    _mreq.imr_interface.s_addr := inet_addr(PAnsiChar(_listeningInterface));
    // Joinig multicast group here. Note the _fd variable usage here.
    if (setsockopt(_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, @_mreq, sizeof(_mreq)) < 0) then Exit;
    end;
    end;

    当我们尝试从用于微 Controller 的 Keil 库中执行此操作时,没有像 setsockopt 这样的函数。为了那个原因。有 igmp_join不接受套接字变量的函数,但只接受多播组。

    结果,我们无法指定UDP端口和多播组的对应关系,每个UDP套接字都成为我们加入的所有组的数据。

    两种方法中哪一种是正确的:Keil 或 Windows?

    最佳答案

    两种行为都是正确的。

    你在哪个socket上接收到哪些UDP数据包超出了IPv4多播的定义范围。

    您只收到您加入群组的流量的期望经常被违反。此外,所有操作系统都以不同的方式实现这一点。 Linux 和 Windows 的行为不同,微 Controller 中的小型 IP 堆栈通常具有更简单的行为。

    基线,您可以预期的最坏情况是:您将在您的 UDP 套接字上收到随机 UDP 数据包,即使来自您未加入的组。但在实践中通常并没有那么糟糕。只是作为思考时的指导方针。原因是:操作系统可能会延迟成员(member)资格的下降。本地路由器将延迟成员资格删除。本地路由器将包含错误。

    无论如何,您都需要处理接收到意外的 UDP 数据包,因为您网络中的任何人都可以伪造 UDP 数据包并以其他人的名义将它们发送到您的套接字。其他任何人都可以伪造 IGMP 数据包并“加入”任何多播组。

    这意味着:在实践中,您总是需要进行应用程序级别的过滤并默默地忽略意外的 UDP 数据包。在大多数 IP 堆栈上,都有一个(重要的)选项来确定接收到的 UDP 数据包的目标地址。这对于拆分多个多播组的流量非常有用。

    由于您现在知道 IP 堆栈的行为,因此您可以节省一些内存,只需使用单个 UDP 套接字来接收所有 UDP 流量并在应用程序端对其进行解复用。当然,这也取决于您的应用程序。

    但是,是的,我理解您对 IP 多播定义如此不明确感到失望。我和你有感觉! :-)

    关于sockets - IP 组播 + UDP : Should I receive data for all groups?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54534879/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com