⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 自己写的多播测试程序
💻 C
字号:
//有两个条件:1 进程必须加入多播组  2 进程必须捆绑某个端口(服务器的多播端口)到UDP套接口
  #include<stdio.h>
  #include<stdlib.h>
  #include<string.h>
  #include<unistd.h>
  #include<sys/socket.h>
  #include<arpa/inet.h>
  #include<netinet/in.h>
  #include<sys/types.h>
  
 const char *host = "224.0.0.1";
 const char *host2 = "192.168.0.13";
 int main( int argc, char **argv )
  {
      char message[256];
      struct ip_mreq mreq;
/*struct ip_mreq{

       struct in_addr imr_multiaddr;       // IPv4 class D multicast addr  D类多播地址
       struct in_addr imr_interface;           // IPv4 addr of local interface 本地接口

};*/
      int on = 1;
      u_char ttl = 12;
      int sockfd;
      struct sockaddr_in servaddr;
      socklen_t socklen;
  
      sockfd = socket( AF_INET, SOCK_DGRAM, 0 );
  
      memset( &servaddr, 0, sizeof(servaddr) );//memset函数用来对一段内存空间全部设置为某个字符,常用于内存空间初始化。将已开辟内存空间 s 的首 n 个字节的值设为值 c
      servaddr.sin_family = AF_INET;
      servaddr.sin_port = htons(10000);
      servaddr.sin_addr.s_addr = htonl(INADDR_ANY);  //INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。 一般来说,在各个系统中均定义成为0值。
								//将主机的无符号长整形数转换成网络字节顺序。
         
      //为了方便在同一电脑上测试多播地址
      if( setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0 )   //SO_REUSEADDR 允许套接口和一个已在使用中的地址捆绑(参见bind())。
      {
          perror( "setsockopt to SO_REUSEADDR" );
          exit(1);
      }
  
          printf( "setsockopt to SO_REUSEADDR\n" );
  
      //允许接收本地回馈 
      on = 1;
      if( setsockopt( sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, &on, sizeof(on) ) < 0 ) //使能或禁止外出多播数据报的回馈
      {
          perror( "setsockopt IP_MULTICAST_LOOP " );
          exit(1);
      }
      printf( "setsockopt IP_MULTICAST_LOOP\n" );

  
      inet_pton(AF_INET, host, &mreq.imr_multiaddr.s_addr);//转换字符串到网络地址,并且多播地址设置为host,即“224.0.0.1”;
      mreq.imr_interface.s_addr = htonl(INADDR_ANY);   //设置本地地址
  
 	//进程必须加入多播组,在mreq结构中要指定多播IP地址,至于接口可以由系统自动分配
      if( setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq) ) < 0 )   //加入多播组
      {
          perror( "setsockopt IP_ADD_MEMBERSHIP " );
          exit(1);
      }
  
          printf( "setsockopt IP_ADD_MEMBERSHIP \n" );
      
        //系统缺省为TTL为1, 也就是只能在本子网段内多播,如果要跨网段需要修改TTL 
      if( setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl) ) < 0 )  //指定外出多播数据报的TTL
      {
          perror( "setsockopt IP_MULTICAST_TTL " );
          exit(1);
      }
  
          printf( "setsockopt IP_MULTICAST_TTL \n" );
  
 //注意:进程必须捆绑该端口(即服务器的多播端口)到UDP套接口,至于套接口可以由系统自动分配也可以手动指定
      if( bind( sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr) ) < 0 )
      {
          perror( "bind error" );
          exit(1);
      }
      perror( "bind " );
  
      on = 0;
      while( on++ < 10 )
      {
          socklen = sizeof(servaddr);
          if( recvfrom( sockfd, message, 256, 0, NULL, NULL ) < 0 )    //接受服务器发送的多播消息,10次
          {
              printf( "recvfrom error" );
              continue;
          }
  
          printf( "%s\n", message );
                }
  
      if( setsockopt( sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq) ) < 0 )  //离开多播组
      {
          perror( "setsockopt IP_DROP_MEMBERSHIP " );
          exit(1);
      }
  
      exit(0);
  }   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -