linux下c++实现udp组播模式

组播:发送的信息,小组内所有成员都能同时接受到。
组播发送端跟接收端的具体流程为:
发送方:
a.创建socket

socket_fd=socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd < 0)
{
    perror("socket multicast!");
    exit(1);
}

b.设置发送的群组的地址

/*set up the destination address*/
memset(&group_addr,0,sizeof(struct sockaddr_in));
group_addr.sin_family = AF_INET;
group_addr.sin_port = htons(group_port);
group_addr.sin_addr.s_addr = inet_addr("230.1.1.1");

c.发送,调用sendto()函数

if (sendto  (socket_fd, recmsg, strlen(recmsg), 0,  (struct sockaddr *) &group_addr,
             sizeof(struct sockaddr_in)) < 0)
{
    printf("sendto error!\n");
    exit(1);
}

接收方:
1.创建socket

socket_fd=socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd < 0)
{
    perror("socket multicast!");
    exit(1);
}

2.(可选)设置多个socket公用同一端口号,如果在同一台电脑中需要多个程序接受的话,需要设置。

/* allow multiple sockets to use the same PORT number */
if(setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0)
{
    perror("Reusing ADDR failed");
    exit(1);
}

3.设置本地地址信息

/*set up the local address*/
memset(&local_addr,0,sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(group_port);              //this port must be the group port

注意:本地的端口必须为群组的端口,地址为本地地址。
4.bind本地地址

/*bind local address*/
if(bind(socket_fd,(struct sockaddr *)&local_addr,sizeof(local_addr)) == -1)
{
    perror("Binding the multicast!");
    exit(1);
}

5.设置群组地址与端口

/*use the setsocketopt() to request joining the multicast group*/
    mreq.imr_multiaddr.s_addr=inet_addr(group_ip);
mreq.imr_interface.s_addr=htonl(INADDR_ANY);

6.加入群组

if(setsockopt(socket_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0)
{
    perror("setsockopt multicast!");
    exit(1);
}

7.接受消息

bzero(recmsg, sizeof(recmsg)-1);
n = recvfrom(socket_fd, recmsg, sizeof(recmsg)-1, 0,(struct sockaddr *)&group_addr, &addr_len);
if (n < 0) {
    printf("recvfrom err in udptalk!\n");
    exit(4);
} else {
/* success recieve the information */
    recmsg[n] = 0;
    printf("peer:%s \n", recmsg);
}

完整代码如下:
发送方:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;


int main(void)
{
    char group_ip[20];
    int group_port = 7838;
    int local_port = 11112;
    strcpy(group_ip,"230.1.1.1");




    char recmsg[256];


     int n;
    int socket_fd;
    struct sockaddr_in group_addr;  //group address
    struct sockaddr_in local_addr;//local address
    struct ip_mreq mreq;
    socklen_t addr_len = sizeof(group_addr);
    u_int yes;


    socket_fd=socket(AF_INET,SOCK_DGRAM,0);
    if(socket_fd < 0)
    {
        perror("socket multicast!");
        exit(1);
    }

    /* allow multiple sockets to use the same PORT number */
    if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0)
    {
        perror("Reusing ADDR failed");
        exit(1);
    }




    /*set up the destination address*/
    memset(&group_addr,0,sizeof(struct sockaddr_in));
    group_addr.sin_family = AF_INET;
    group_addr.sin_port = htons(group_port);
    group_addr.sin_addr.s_addr = inet_addr("230.1.1.1");




    /*set up the local address*/
    memset(&local_addr,0,sizeof(local_addr));
    local_addr.sin_family = AF_INET;
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    local_addr.sin_port = htons(group_port);              //this port must be the group port
    /*bind local address*/
    if(bind(socket_fd,(struct sockaddr *)&local_addr,sizeof(local_addr)) == -1)
    {
        perror("Binding the multicast!");
        exit(1);
    }
    /*use the setsocketopt() to request joining the multicast group*/
    mreq.imr_multiaddr.s_addr=inet_addr(group_ip);
    mreq.imr_interface.s_addr=htonl(INADDR_ANY);
    if (setsockopt(socket_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0)
    {
        perror("setsockopt multicast!");
        exit(1);
    }
   /*loop to send or recieve*/
   while(1)
   {
       /*send*/
       bzero(recmsg, sizeof(recmsg));
       if (fgets(recmsg, sizeof(recmsg), stdin) == (char *) EOF)
       {
           exit(0);
        }
       if (sendto  (socket_fd, recmsg, strlen(recmsg), 0,  (struct sockaddr *) &group_addr,
                sizeof(struct sockaddr_in)) < 0)
       {
           printf("sendto error!\n");
           exit(3);
       }
       printf("'%s' send ok\n", recmsg);





   }




}

接收方:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;


int main(void)
{
    char group_ip[20];
    int group_port = 7838;
    int local_port = 11112;
    strcpy(group_ip,"230.1.1.1");




    char recmsg[256];


     int n;
    int socket_fd;
    struct sockaddr_in group_addr;  //group address
    struct sockaddr_in local_addr;//local address
    struct ip_mreq mreq;
    socklen_t addr_len = sizeof(group_addr);
    u_int yes;


    socket_fd=socket(AF_INET,SOCK_DGRAM,0);
    if(socket_fd < 0)
    {
        perror("socket multicast!");
        exit(1);
    }

    /* allow multiple sockets to use the same PORT number */
    if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0)
    {
        perror("Reusing ADDR failed");
        exit(1);
    }




    /*set up the destination address*/
    memset(&group_addr,0,sizeof(struct sockaddr_in));
    group_addr.sin_family = AF_INET;
    group_addr.sin_port = htons(group_port);
    group_addr.sin_addr.s_addr = inet_addr("230.1.1.1");




    /*set up the local address*/
    memset(&local_addr,0,sizeof(local_addr));
    local_addr.sin_family = AF_INET;
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    local_addr.sin_port = htons(group_port);              //this port must be the group port
    /*bind local address*/
    if(bind(socket_fd,(struct sockaddr *)&local_addr,sizeof(local_addr)) == -1)
    {
        perror("Binding the multicast!");
        exit(1);
    }
    /*use the setsocketopt() to request joining the multicast group*/
    mreq.imr_multiaddr.s_addr=inet_addr(group_ip);
    mreq.imr_interface.s_addr=htonl(INADDR_ANY);
    if (setsockopt(socket_fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0)
    {
        perror("setsockopt multicast!");
        exit(1);
    }
   /*loop to send or recieve*/
   while(1)
   {

       bzero(recmsg, sizeof(recmsg)-1);
       n = recvfrom(socket_fd, recmsg, sizeof(recmsg)-1, 0,
               (struct sockaddr *) &group_addr, &addr_len);
       if (n < 0) {
           printf("recvfrom err in udptalk!\n");
           exit(4);
       } else {
           /* success recieve the information */
           recmsg[n] = 0;
           printf("peer:%s \n", recmsg);
       }

   }




}

另:如果使用多线程进行接受发送,接收时的recvfrom函数中地址不能使用group的地址进行接受,应当另随便写一个。

你可能感兴趣的:(C++)