组播


组播通过测试,双网卡或多网卡设置在不同IP段。

IP地址空间被划分为A、B、C三类。第四类即D类地址被保留用做组播地址。在第四版的IP协议(IPv4)中,从224.0.0.0到239.255.255.255间的所有IP地址都属于D类地址。所以要利用组播发送数据必须有一个虚拟的组播IP,所谓虚拟,就是你不必把网卡地址设为此IP,而只需在你程序中出现,相当于建立一个以此IP为标志的集合,所有想加入组播的必须加入这个集合之中,发送组播时,往此IP发送,所有此集合中的主机均可接收到相同的数据,其处理转发过程由上一级路由器或者集线器处理。一台主机可以加入到多个组播组之中,一个组播组可以含有多台主机,但是这些主机必须在同一IP段,即在同一个路由之下。

下面一个程序可以实现UDP组播的发送与接收。只能发送或者只能接收,如果都想,自己建个进程或线程吧,把程序放进去就行。

//头文件

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <netdb.h>

//全局变量定义

char host_name[] = "239.5.5.5";      //组播IP地址

char local_IP[] = "192.168.2.10";     //本机IP地址

char mess_send[]="hello";          //待发数据

//char mess_rec[1024];             //接收缓冲

int port = 5115;                   //端口号

//主程序

int main()

{

  struct ip_mreq command;

  int loop = 1;

  int i = 0;

   /* 多播循环 */

  int  iter = 0;

  int  sin_len;

  int  sFd1;

  struct sockaddr_in sin,address;     //本机、目标机socket参数

  /****************发送目标机Socket赋值*********************/

 memset(&address, 0, sizeof(address));  

 address.sin_family = AF_INET; 

 address.sin_addr.s_addr = inet_addr(host_name);

 address.sin_port = htons(port);

  /***************本机Socket赋值***********************/

    if((sFd1 = socket(AF_INET, SOCK_DGRAM, 0)) == -1)

    {

      perror("***********************socket1*****************\n");

      exit(-1);

    }

  memset(&sin, 0, sizeof(sin));

  sin.sin_family = AF_INET;

  sin.sin_addr.s_addr = htonl(INADDR_ANY);

  sin.sin_port = htons(port);

 if(bind(sFd1,(struct sockaddr *)&sin, sizeof(sin)) < 0)

   {

     perror("***********************bind1********************\n");

     exit(-1);

    }

/*将本地IP绑定到相应组播上,经过测试,如果只有一块网卡,或者有多快网卡,只是用第一块(默认的)可以不设置,但是如果有多块网卡,或者使用多块网卡中的非默认的,必须绑定*/

 loop = 1;

 unsigned long seladdr;

 seladdr = inet_addr(local_IP);

 if(setsockopt(sFd1,IPPROTO_IP, IP_MULTICAST_IF,(char *)&seladdr, sizeof(seladdr)) < 0)

  {  

  perror("setsockopt:IP_MULTICAST_LOOP");

   exit(-1);

   }

 /* 加入一个组播组,支持组播,进一步告诉Linux内核,特定的套接口即接受广播数据*/

 command.imr_multiaddr.s_addr = inet_addr(host_name);

 //command.imr_interface.s_addr = htonl(INADDR_ANY);

 command.imr_interface.s_addr = inet_addr(local_IP);

  if(command.imr_multiaddr.s_addr == -1)

 perror("224.0.0.1 not a legal multicast address");

 exit(-1);

}

  if (setsockopt(sFd1, IPPROTO_IP, IP_ADD_MEMBERSHIP,&command, sizeof(command)) < 0)

 {  

  perror("setsockopt:IP_ADD_MEMBERSHIP\n");

 }

//以下接收数据

/*while(i++ < 50)

{   

sin_len = sizeof(sin);

//   memset(&message, 0, sizeof(message));

  if(recvfrom(sFd1, message, 256, 0, (struct sockaddr *)&sin, &sin_len) == -1)

   {

      perror("***********************recvfrom********************\n");  

    }

    printf("receive: %s\n",message);

   

}

*/

//以下发送数据

 while(i< 200)

 {

    i++;

    printf("%d\n",i);

    sleep(1);

 if(sendto(sFd1, message,  sizeof(message), 0,(struct sockaddr *)&address, sizeof(address)) < 0)

 perror("************************sendto****************************\n"); 

 exit(-1);

 }

}

//结束

close(sFd1);

return 0;

}

你可能感兴趣的:(linux)