c++ - 多播接收器套接字中的重复数据包

标签 c++ c sockets multicast setsockopt

<分区>

在下面的 MulticastReceiver 实现中似乎有一个错误。

在为 <224.0.25.46,13001> 和 <224.0.25.172,13001> 创建两个实例时,我在每个流中获取每个数据包两次。任何指针?我猜是 REUSEADDR ?

class MulticastReceiverSocket {
  protected:
    const std::string listen_ip_;
    const int listen_port_;
    int socket_file_descriptor_;
  public:

  MulticastReceiverSocket ( const std::string & listen_ip, 
                            const int listen_port )
    : listen_ip_ ( listen_ip ), listen_port_ ( listen_port ), 
      socket_file_descriptor_ ( -1 )
  { 

  /* create socket to join multicast group on */
  socket_file_descriptor_ = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
  if ( socket_file_descriptor_ < 0 ) 
    { exit(1); }

  /* set reuse port to on to allow multiple binds per host */
  {
    int flag_on = 1;
    if ( ( setsockopt ( socket_file_descriptor_, SOL_SOCKET, 
                        SO_REUSEADDR, &flag_on,
                        sizeof(flag_on) ) ) < 0 ) 
      { exit(1); }
  }

  McastJoin ( );

  {
    /* construct a multicast address structure */
    struct sockaddr_in mcast_Addr;
    bzero ( &mcast_Addr, sizeof(mcast_Addr) );
    mcast_Addr.sin_family = AF_INET;
    mcast_Addr.sin_addr.s_addr = htonl(INADDR_ANY);
    mcast_Addr.sin_port = htons ( listen_port_ );

    /* bind to specified port onany interface */
    if ( bind ( socket_file_descriptor_, (struct sockaddr *) &mcast_Addr, sizeof ( struct sockaddr_in ) ) < 0 ) 
       { exit(1); } 
  }
}

void McastJoin ( )
{ 
    /* construct an IGMP join request structure */

    struct ip_mreq mc_req;
    inet_pton ( AF_INET, listen_ip_.c_str(), &(mc_req.imr_multiaddr.s_addr) ); 
    mc_req.imr_interface.s_addr = htonl(INADDR_ANY);

    /* send an ADD MEMBERSHIP message via setsockopt */
    if ( ( setsockopt ( socket_file_descriptor_, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
                (void*) &mc_req, sizeof(mc_req))) < 0) 
    {
      printf ("setsockopt() failed in IP_ADD_MEMBERSHIP %s\n", listen_ip_.c_str() );
      exit(1);
    } 

}

inline int ReadN ( const unsigned int _len_, void * _dest_ ) 
{
  if ( socket_file_descriptor_ != -1 )
    {
      return recvfrom ( socket_file_descriptor_, _dest_, _len_, 0, NULL, NULL );
    }
  return -1;
}

请指教,当然也请指出可以做的任何改进、优化。

最佳答案

替换

mcast_Addr.sin_addr.s_addr = htonl(INADDR_ANY);

mcast_Addr.sin_addr.s_addr = inet_addr (mc_addr_str);

这对我 (linux) 很有帮助,对于每个应用程序,我从一个端口上的单独 mcast 组接收单独的 mcast 流。

您还可以查看 VLC 播放器源代码,它在一个端口上显示来自不同 mcast 组的许多 mcast iptv channel ,但我不知道它是如何分离 channel 的。

关于c++ - 多播接收器套接字中的重复数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4957042/

相关文章:

c++ - 使用 C++ 中的 Eigen 库定义和填充稀疏矩阵

c++ - 如何在 C++ 中打印 Unicode 字符

c - 在 C 宏扩展期间,是否存在扩展为 "/*"的宏的特殊情况?

c - 有没有办法在循环中打印结构成员而无需在 C 中命名每个成员?

c - 将参数传递给 bind() 函数

c++ - 如何在std::function上使用模板扩展

c - 如何在结构中将 char + int 存储为相同类型和相同成员?

c++ - 取消挂起的接收?

java - 如何取消阻塞在 ServerSocket.accept() 上阻塞的线程?

c++ - 在 C/C++ 中查找字符串中具有任意字符顺序的子字符串