如何从已经订阅的组中接收多播数据包
How to receive multicast packets from already subscribed group?
在我的ubuntu 16.04系统中,我运行以下程序:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#define HELLO_PORT 12345
#define HELLO_GROUP "225.0.0.37"
#define MSGBUFSIZE 256
main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, nbytes,addrlen;
struct ip_mreq mreq;
char msgbuf[MSGBUFSIZE];
u_int yes=1;
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(HELLO_GROUP);
addr.sin_port=htons(HELLO_PORT);
/* bind to receive address */
if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP);
mreq.imr_interface.s_addr=htonl(INADDR_ANY);
if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) {
perror("setsockopt");
exit(1);
}
}
此程序只是订阅了我的系统以接收组225.0.0.37
的多播UDP数据包在本地网络中的另一个系统上,我有另一个程序,该程序会定期将数据包发送到此组
使用上述程序订阅了该组后,我验证了我从Wireshark
获得了UDP数据包的225.0.0.37我想通过另一个程序阅读这些传入数据包。而且我不想使用原始插座。以下是我编写的另一个程序:
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>
using boost::asio::ip::udp;
static const int max_length = 1024;
char data_[max_length];
void handle_receive_from(const boost::system::error_code& error, size_t bytes_recvd)
{
std::cout.write(data_, bytes_recvd);
}
int main(int argc, char* argv[])
{
try
{
boost::asio::io_service io_service;
udp::endpoint local_endpoint = boost::asio::ip::udp::endpoint(
boost::asio::ip::address::from_string("225.0.0.37"), boost::lexical_cast<int>("12345"));
std::cout << "Bind " << local_endpoint << std::endl;
udp::socket socket(io_service);
socket.open(local_endpoint.protocol());
socket.set_option(udp::socket::reuse_address(true));
socket.bind(local_endpoint);
socket.async_receive(
boost::asio::buffer(data_, max_length),
boost::bind(&handle_receive_from,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
即使我看到数据包通过Wireshark,该程序也不会获取任何数据。我究竟做错了什么?是否可以获取数据?总体问题是:我可以在一个程序中订阅一个多播组并在另一个程序中接收数据包?
它取决于。
如果您的第一个程序很快就会退出,则OS将关闭套接字,发送IGMP休假,因此您的第二个程序将不会收到任何多播数据包。因此,您应该保持第一个程序运行(将函数添加到永远屏蔽),以免它留下多播组。
实际上,Linux内核跟踪每个插座的组成员资格,似乎并没有用来过滤多播数据包。因此,您可以在一个程序中订阅一个多播组,然后在另一个程序中接收数据包,直到取消订阅(在我的Ubuntu 14.04上使用)。不确定此策略是否会改变,但是在我的OS X 10.10上,它不允许这样做。
相关文章:
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 发送固定大小的 UDP 数据包
- 是否可以将多个结构作为一个数据包存储在一个函数中,然后传递给其他函数并在那里提取?
- 使用 Qt 通过蓝牙发送多个原始数据包
- 使用FFMPEG编写多线程视频和音频数据包
- 如何从已经订阅的组中接收多播数据包
- 如何正确接收多播UDP数据包
- 具有Boost C 的多播接收器看不到数据
- UDP插座(多播)未接收数据(Ubuntu)
- C++TCP Winsock服务器多次接收相同的数据包
- 数据包转换为具有多个动态数组的结构
- Solaris 10 -- 从 recvmsg() 的 UDP 组播数据包中获取 IP 源地址
- 具有多个逻辑数据流的单个套接字连接(区分数据包)
- 多播大数据包包含多个客户端的所有信息,而单个数据包则包含目标客户端的信息
- 从多个文件描述符异步接收UDP数据包
- 以最低的延迟从linux中的多播套接字接收数据
- 如何使多播套接字不接收单播数据?
- 多播基础-丢失数据
- C++停止CAsyncSocket将单个大数据包拆分为多个小数据包