簡體   English   中英

我需要 2 個套接字來進行多播發送和單播讀取嗎?

[英]do i need 2 sockets for multicast send and unicast read?

我正在 Linux 上使用 C/C++ 中的 udp 套接字處理客戶端/服務器項目。 在服務器端,需要寫組播,讀單播。 在客戶端,需要讀組播,寫單播。 不能使用第 3 方庫。 只有 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM