多个接口上的多个组播
multiple multicast on multiple interfaces
OS: CentOS 5.5
语言: C++
对此做了相当多的研究,但我找不到任何文章来做我所拥有的这种确切设置。这是一个非常具体的设置,所以我将尽力描述我正在做什么和我正在尝试做什么。
我有一台带有 2 个以太网端口(eth0 和 eth1)的计算机。每个同时接收不同的组播广播。因此,1 个组播 IP 地址和端口将转到 eth0,另一个组播 IP 地址和端口将转到 eth1。
我正在编写一个旨在侦听给定组播 IP 地址和端口的程序。
目标是能够启动程序并侦听其中一个组播,同时启动侦听另一个组播的程序的第 2 个实例。该程序本身设计为一次只能收听 1 个组播。
但是,我似乎无法同时运行两个程序。
使用"route"命令,我已经能够设置路由表,我可以在其中接收其中一个流,但不能接收另一个流。我一次只能获得 1 个流,但不能同时运行两个流。
eth0 连接到:10.10.20.50 -- 此接口的组播为 225.0.7.10 端口 51007eth1 连接到:192.168.20.21 -- 此接口的组播为 225.0.8.10 端口 51008
如果我执行路由命令"路由添加默认 gw 10.10.20.50 eth0",我可以很好地接收该地址上的组播
但是一旦我添加"路由添加默认 gw 192.168.20.21 eth1",我就无法再在 10.10.20.50 接口上接收组播。
我在绑定套接字或设置袜子时没有收到任何错误......该程序只是简单地阻止 recv 调用,永远不会收到消息。
我已经尝试了路由命令的各种组合来支持这一点,并且我也在我的连接代码中做了一些不同的事情来解决这个问题,但没有运气。这是我当前的连接代码:
//Create the UDP socket, check to make sure it was created successfully
cout << "Initializing Connection..." << endl ;
m_socket = socket ( AF_INET , SOCK_DGRAM , IPPROTO_UDP ) ;
if( m_socket == -1 )
{
cout << "ERROR CREATING SOCKET: " << strerror(errno) << endl ;
return false ;
}
cout << "Socket Created" << endl;
//Setup socket binding information
sockaddr_in addr ;
bzero ( ( char* ) &addr , sizeof ( addr ) ) ;
addr . sin_family = AF_INET ;
addr . sin_addr.s_addr = inet_addr(interface_addr) ; //10.10.20.50 or 192.168.20.21
addr . sin_port = htons ( port ) ; //51007 or 51008
//bind the socket, check for errors
int result = bind ( m_socket , ( struct sockaddr* ) &addr , sizeof ( addr ) ) ;
if ( result == -1 )
{
cout << "ERROR BINDING PORT: " << strerror ( errno ) << endl;
shutdown ( m_socket , SHUT_RDWR ) ;
return false ;
}
cout << "Socket Bound" << endl;
//subscribe to the supplied IP address and port to listen on
in_addr host_addr ;
inet_pton ( AF_INET , ip_addrs . c_str () , & ( host_addr ) ) ;
struct ip_mreq mreq;
mreq . imr_multiaddr = host_addr ; // multicast address 225.0.7.10 or 225.0.8.10
mreq . imr_interface = addr . sin_addr ; //the 10.10.20.50 or 192.168.20.21 specified above
result = setsockopt ( m_socket , IPPROTO_IP , IP_ADD_MEMBERSHIP, &mreq , sizeof(mreq) ) ;
if ( result == -1 )
{
cout << "ERROR SETTING SOCKOPT SUBSCRIPTION: " << strerror(errno) << endl ;
printSocketError();
shutdown ( m_socket , SHUT_RDWR ) ;
return false ;
}
/*
* Read from the socket to get the initial bit of information we need so the
* buffers can get allocated correctly, and the width and height of the application
* can be defined.
*/
cout << "Attempting to read from the socket..." << endl;
MyPacket pckt ;
recv ( m_socket , &pckt , sizeof ( pckt ) , MSG_PEEK ) ;
cout << "Data Received... processing" << endl ;
我还尝试使用 ip_mreqn 结构手动指定接口,并使用 setsockopt 进行SOL_BINDTODEVICE设置(eth0 或 eth1),但遇到了与以前相同的问题,如果我有特定的路由设置,我只能让它连接......即便如此,也只有 1 个会收到,而另一个不会。
重申...我需要同时运行该程序的 2 个副本。每个侦听它自己指定的来自特定接口的组播地址。
您需要设置两个不同的路由,以便将不同的组路由到(从而侦听)给定的接口:
root:~# route add -net 225.0.7.10 netmask 255.255.255.255 dev eth0
root:~# route add -net 225.0.8.10 netmask 255.255.255.255 dev eth1
然后,当您的程序运行时,您应该能够看到哪些组在哪个接口上收听了netstat -ng
。
编辑 0:
shutdown(2)
调用仅适用于 TCP,对 UDP 没有任何意义。- 查看"UNIX Network Programming, The Sockets Networking API", Volume 1。它有一个关于如何正确执行此操作的详细章节。书中的代码是免费提供的。
编辑 1:
获取我提到的UNP书籍的源代码,它在这里。查看解压缩存档中的unpv13e/lib
目录,读取mcast_join.c
文件。
而是这样做 -1. 创建一个类。2. 有一个函数来创建和绑定该类中的 IP 和端口。3. 使用该类 Object 从主函数调用该函数两次。
要验证结果,您可以使用命令 netstat -g,它将显示与您的多播 IP 对应的两个实例。
如果你愿意,我可以编码,但先自己尝试
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- Visual C++GC接口如何启用它以及要包含哪个库
- Windows.h与GLFW.h的接口
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 提供与TMP和SFINAE的通用接口
- 为重写std::exception的库生成swig接口时出错
- 内联如何影响模块接口中的成员函数
- COM 接口 c# 封送数组数组
- 如何在 SCIP C++ 接口中获取 MILP 约束矩阵中的系数值
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 如何绑定 C++ gRPC 客户端的网络接口
- 模板化接口 - 创建一个泛型模板类以返回任何容器
- 如何从实现接口的模板化类实例访问结构
- 带有进度表的 curl 多接口程序
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 我可以在具有一个标头和一个接口的 cpp 文件中有多个嵌入吗?
- 类接口,可以创建N个方法
- 类具有相同的接口,但参数的类型不同
- 如何与 Cheerp/js 中的 extern 变量接口?
- 如何使用现代 CMake 安装捆绑的接口依赖项?