c++ - 我需要 2 个套接字来进行多播发送和单播读取吗?

标签 c++ linux sockets udp multicast

我正在 Linux 上的 C/C++ 中使用 udp 套接字开发客户端/服务器项目。在服务器上,需要写入多播和读取单播。在客户端,需要读多播和写单播。无法使用第三方库。仅GLIBC

客户端和服务器都需要 2 个套接字吗?一个套接字用于多播,一个套接字用于单播?

顺便说一句,IP 地址和端口都已给出。

预先感谢您的所有帮助。

这是我的代码,

服务器

// open a UDP socket
m_sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_IP );

if ( m_sock < 0 )
{
    std::cerr << "ERROR: create socket failed ..." << std::endl;
    return( false );
}

m_saddr.sin_family = AF_INET;
m_saddr.sin_port = htons(0);          // Use the first free port 
m_saddr.sin_addr.s_addr = htonl(INADDR_ANY); // bind socket to any interface

// Disable loopback
char loopch{ 0 };

int rc = setsockopt( m_sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopch, sizeof( loopch ) );

if ( rc < 0 )
{
   std::cerr << "ERROR: setsockopt( ) to disable loopback failed, rc = " 
                    << rc << std::endl;                                                                
   return( false );
}

// Set local interface for outbound multicast datagrams.
// The IP address specified must be associated with a local
// multicast capable interface.
m_localInterface.s_addr = htonl( INADDR_ANY );

rc = setsockopt( m_sock, IPPROTO_IP, IP_MULTICAST_IF, (char*)&m_localInterface,sizeof(m_localInterface) );

if ( rc < 0)
{
   std::cerr << "ERROR: Setting local interface failed, rc: " << rc << std::endl;
   return( false );
}

rc = bind( m_sock, (struct sockaddr *)&m_saddr, sizeof( struct sockaddr_in ) );

if ( rc < 0 )
{
   std::cerr << "ERROR: binding socket to interface failed ..." << std::endl;
   exit( -1 );
}
m_saddr.sin_family = AF_INET;
m_saddr.sin_port = htons( UDP_PORT );
m_saddr.sin_addr.s_addr = inet_addr( UDP_ADDRESS );

客户端代码

// open a UDP socket
m_sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_IP );
if ( m_sock < 0 )
{
   std::cerr << "ERROR: create socket failed ..." << std::endl;
   return( false );
}

m_saddr.sin_family      = AF_INET;
m_saddr.sin_port        = htons( UDP_PORT ); // listen on port defined UDP_PORT    
m_saddr.sin_addr.s_addr = htonl(INADDR_ANY); // bind socket to any interface

// Disable loopback
char loopch{ 0 };

int rc =  setsockopt( m_sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopch, sizeof( loopch ) );

if ( rc < 0 )            
{
   std::cerr << "ERROR: setsockopt( ) to disable loopback failed, rc = " 
             << rc << std::endl;

    return( false );
}

rc = bind( m_sock, (struct sockaddr *)&m_saddr, sizeof( struct sockaddr_in ) );

if ( rc < 0 )
{
   std::cerr << "ERROR: binding socket to interface failed ..." << std::endl;
   exit( -1 );
}

// JOIN multicast group on default interface        
m_imreq.imr_multiaddr.s_addr = inet_addr( UDP_ADDRESS );
m_imreq.imr_interface.s_addr = htonl( INADDR_ANY ); // use DEFAULT interface

rc = setsockopt( m_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&m_imreq, sizeof( struct ip_mreq ) );

if ( rc < 0)
{
   std::cerr << "ERROR: Setting local interface error" << std::endl;
    return false;
}

socklen_t m_socklen = sizeof(struct sockaddr_in);

while ( 1 )
{
    rc = recvfrom( m_sock, buffer, MAX_BUFFER_SIZE, 0, 
            (struct sockaddr *)&m_saddr, &m_socklen );

    if ( rc < 0 )
    {
        std::cerr << "ERROR: receive multicast message failed ..." << std::endl;

         break;
     }
     else
     {
         std::cout << "Received multicast ..." << std::endl;                
     }
}

最佳答案

是的,您可以为每个进程使用一个套接字来完成此操作。您应该将所有内容设置为仅接收(不要调用 connect()),然后使用 sendto() 将数据报发送到指定地址。

引用号:https://linux.die.net/man/3/sendto

关于c++ - 我需要 2 个套接字来进行多播发送和单播读取吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54836535/

相关文章:

c++ - 使用堆栈添加带有组件的 2 个 vector 组件

linux - 何时不将 -r 与 cp 一起使用?

c# - UDP 客户端 - 创建套接字时出现异常通常只允许每个套接字地址(协议(protocol)/网络地址/端口)使用一次

c++ - 根据另一个数组对一个数组进行排序

c++ - 为什么 TCP socket 在收到错误的 ACK 时发送 RST 数据包而不是重新发送数据?

c++ - QT 文件菜单未集成到标题栏中

linux - 如何将搜索路径添加到 "which"中?

c++ - Linux 中的 OpenCV:无法获取 Mat 大小(cv::Size),仅返回 MSize

java - 如何决定在套接字通信中使用哪个端口

Java通过套接字发送文件