什么意思组播(UDP)套接字绑定?什么意思组播(UDP)套接字绑定?(What does it me

2019-05-14 09:30发布

我使用具有多个网络接口的主机之间的多播UDP。 我使用boost :: ASIO,而且我在2个操作接收机困惑已经做出:绑定,然后加入群。

为什么你需要指定接口的本地地址,绑定过程中,当你做到这一点与您加入的每个组播组?

小姑问题关于多播端口:由于在发送过程中,发送到多播地址和端口,为什么,订阅一个组播组中,只指定地址,而不是端口 - 在混乱调用被指定的端口绑定。

注:“加入群”是在包装setsockopt(IP_ADD_MEMBERSHIP)其作为记录,可称为同一插座上多次订阅不同的群体(在不同的网络?)。 因此,它将使完美的意义沟绑定调用和指定端口每次我订阅论坛的时间。

从我所看到的,总是结合“0.0.0.0”和加入该组时指定的接口地址,工作得非常好。 困惑。

Answer 1:

绑定一个UDP套接字时接收多播装置到指定的地址和端口从其接收数据(不是本地接口,如对于TCP受体结合的情况下)。 在这种情况下,指定的地址具有过滤作用,即套接字将只接收发送到多播地址和端口,不管什么团体由插座随后加入数据报。 这就解释了为什么(0.0.0.0)绑定到INADDR_ANY当我收到发送到我的组播组的数据报,而当绑定到任何本地接口我没有收到任何东西,即使正在网络上发送的数据包到该接口对应。

从UNIX®网络编程第1卷报价,第三版:由WR史蒂文斯套接字联网API。 21.10。 发送和接收

[...]我们希望接收套接字绑定的多播组和端口,说239.255.1.2的端口8888(回想一下,我们可以只绑定通配符IP地址和端口号8888,但结合多播地址防止插座从接收可能到帐往端口8888的任何其它数据包),然后我们想接收套接字来加入组播组。 发送套接字将数据报发送给这个相同的组播地址和端口,说239.255.1.2的端口8888。



Answer 2:

在“绑定”操作基本上是说,“使用本地UDP端口用于发送和接收数据。换句话说,它分配UDP端口为您的应用程序独占使用。(同样适用于TCP套接字真)。

当您绑定到“0.0.0.0”( INADDR_ANY ),你基本上说的是TCP / IP层使用所有可用适配器的听力和选择最佳适配器发送。 这是大多数套接字代码标准的做法。 你不会对IP地址指定为0的唯一情况是当你想要发送/接收特定的网络适配器上。

同样,如果你绑定在指定为0,端口值,操作系统将指派该插座随机提供的端口号。 所以,我希望为UDP组播,绑定到INADDR_ANY在哪里组播流量预计将发送至特定端口号。

“加入组播组”操作( IP_ADD_MEMBERSHIP需要的),因为它主要是告诉您的网络适配器听不仅为以太网数据帧在目的MAC地址是你自己的,它也告诉了以太网适配器( NIC )来监听IP组播流量以及为相应的组播以太网地址。 每个组播IP映射到多播以太网地址。 当使用一个插座以发送到一个特定的多播IP,以太网帧的目的地MAC地址被设置为相应的多播MAC地址的多播IP。 当你加入某个组播组,正在配置的NIC监听发送到相同的MAC地址(除了它自己)的交通。

如果没有硬件支持,组播也不会有任何比普通的广播IP报文更高效。 加入操作也告诉您的路由器/网关与其它网络的组播转发。 (还有人记得MBONE?)

如果你加入某个组播组,全部用于对IP地址的所有端口的组播流量将被网卡接收。 只有发往您绑定的监听端口的流量会获得通过的TCP / IP协议栈到应用程式。 在关于为什么播订制过程中指定的端口 - 这是因为IP组播就是这样 - 只有IP。 “端口”是的上层协议(UDP和TCP)的性质。

你可以阅读更多关于IP地址如何组播映射到多播以太网地址在不同地点。 维基百科的文章是关于尽善尽美:

IANA的拥有OUI MAC地址01:00:5E,因此多播数据包,通过使用以太网MAC地址范围传送01:00:5E:00:00:00 - 01:00:5E:7F:FF:FF。 这是可用的地址空间的23位。 第一个八位字节(01)包括所述广播/多播位。 28位的多播IP地址的低23位被映射到可用的以太网地址空间的23位。



Answer 3:

校正是什么意思到组播(UDP)套接字绑定? 只要在下面的引用部分正确:

在“绑定”操作基本上是说,“使用本地UDP端口用于发送和接收数据。换句话说,它分配UDP端口为您的应用程序独占使用

有一个例外。 多个应用程序可以共享收听(多播数据报通常具有实用价值)相同的端口,如果SO_REUSEADDR应用的选项。 例如

int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // create UDP socket somehow
...
int set_option_on = 1;
// it is important to do "reuse address" before bind, not after
int res = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &set_option_on, 
    sizeof(set_option_on));
res = bind(sock, src_addr, len);

如果几个进程没有这样的“重用结合”,那么该共享端口上接收到的每个UDP数据报将被输送至每个处理(提供与多播流量自然关节)的。

下面是关于在少数情况下会发生什么情况的详细信息:

  1. 任何绑定(“独家”或“再利用”)到自由港的尝试将会成功

  2. 试图“专一结合”会,如果该端口已经是“重用绑定”失败

  3. 试图“重用结合”会失败,如果某些过程使“专一结合”



Answer 4:

这也是非常重要的,从接收多播插槽区分发送组播插座。

我同意上述关于接收多播套接字的所有问题的答案。 该OP指出,接收插座结合的接口并没有帮助。 然而,有必要结合组播SENDING插座的接口。

对于多宿主服务器上发送组播插座,这是非常重要的创造要发送到每个接口都有一个单独插座。 一个绑定的发送者的套接字应该为每个接口创建。

  // This is a fix for that bug that causes Servers to pop offline/online.
  // Servers will intermittently pop offline/online for 10 seconds or so.
  // The bug only happens if the machine had a DHCP gateway, and the gateway is no longer accessible.
  // After several minutes, the route to the DHCP gateway may timeout, at which
  // point the pingponging stops.
  // You need 3 machines, Client machine, server A, and server B
  // Client has both ethernets connected, and both ethernets receiving CITP pings (machine A pinging to en0, machine B pinging to en1)
  // Now turn off the ping from machine B (en1), but leave the network connected.
  // You will notice that the machine transmitting on the interface with
  // the DHCP gateway will fail sendto() with errno 'No route to host'
  if ( theErr == 0 )
  {
     // inspired by 'ping -b' option in man page:      
     //      -b boundif
     //             Bind the socket to interface boundif for sending.
     struct sockaddr_in bindInterfaceAddr;
     bzero(&bindInterfaceAddr, sizeof(bindInterfaceAddr));
     bindInterfaceAddr.sin_len = sizeof(bindInterfaceAddr);
     bindInterfaceAddr.sin_family = AF_INET;
     bindInterfaceAddr.sin_addr.s_addr = htonl(interfaceipaddr);
     bindInterfaceAddr.sin_port = 0; // Allow the kernel to choose a random port number by passing in 0 for the port.
     theErr = bind(mSendSocketID, (struct sockaddr *)&bindInterfaceAddr, sizeof(bindInterfaceAddr));
     struct sockaddr_in serverAddress;
     int namelen = sizeof(serverAddress);  
     if (getsockname(mSendSocketID, (struct sockaddr *)&serverAddress, (socklen_t *)&namelen) < 0) {
        DLogErr(@"ERROR Publishing service... getsockname err");
     }
     else
     {
        DLog( @"socket %d bind, %@ port %d", mSendSocketID, [NSString stringFromIPAddress:htonl(serverAddress.sin_addr.s_addr)], htons(serverAddress.sin_port) );
     }

没有此修复程序,组播发送将间歇性获得的sendto()错误号“没有到主机的路由”。 如果任何人都可以阐明为什么拔掉一个DHCP网关光引起的Mac OS X组播SENDING插座感到困惑,我很乐意听到它。



文章来源: What does it mean to bind a multicast (UDP) socket?