zoukankan      html  css  js  c++  java
  • linux 广播和组播

    广播和组播

    广播,必须使用UDP协议,是只能在局域网内使用,指定接收端的IP为*.*.*.255后,发送的信息,局域网内的所有接受端就能够接到信息了。

    广播的发送端代码

    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(int agrc, char** argv){
    
      int fd = socket(AF_INET, SOCK_DGRAM, 0);
    
      int port = atoi(argv[1]);
      struct sockaddr_in addr;
      addr.sin_family = AF_INET;
      addr.sin_port = htons(port);
      addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    
      
      bind(fd, (struct sockaddr*)&addr, sizeof(addr));
      
      int n = 1;
      int ret =  setsockopt(fd, SOL_SOCKET, SO_BROADCAST,
    			&n, sizeof(n));
      
      struct sockaddr_in client;
      memset(&client, 0, sizeof(client));
      client.sin_family = AF_INET;
      client.sin_port = htons(6666);
      inet_pton(AF_INET, "10.210.65.255", &client.sin_addr.s_addr);
      
      int cnt = 0;
      while(1){
        char buf[64] = {0};
        sprintf(buf, "count=%d", cnt++);
        int ret = sendto(fd, buf, sizeof buf, 0, (struct sockaddr*)&client, sizeof(client));
        if(ret == -1){
          perror("sendto -1");
        }
        sleep(1);
      }
      
    }
    
    

    注意点:

    • 必须用setsockopt函数开通套接字的组播权限。注意n的值不能为0.

    • 由于广播的时候,必须指定接收端的端口号,所以接收端必须调用bind函数,显示的指定自己用的端口号。

    接收广播发送信息的代码

    #include <sys/types.h> 
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    
    int main(int agrc, char** argv){
    
      int fd = socket(AF_INET, SOCK_DGRAM, 0);
    
      struct sockaddr_in addr;
      memset(&addr, 0, sizeof(addr));
      addr.sin_family = AF_INET;
      addr.sin_port = htons(6666);
      //addr.sin_addr.s_addr = htons(INADDR_ANY);
      inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr.s_addr);
      socklen_t len = sizeof(addr);
    
      bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    
      
      while(1){
        char buf[64] = {0};
        int ret = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
        write(STDOUT_FILENO, buf, ret);
        sleep(1);
      }
    }
    
    

    注意点:

    • 由于广播的时候,必须指定接收端的端口号,所以接收端必须调用bind函数,显示的指定自己用的端口号。

    组播,必须使用UDP协议。有专门的组播地址。首先发送端要指定一个组播的IP,并且接收端也需要指定和发送端一样的组播的IP。

    组播的IP介绍:

    224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
    
    224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;
    
    224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
    
    239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。
    

    组播发送端例子

    #include <sys/types.h> 
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <net/if.h>
    
    int main(int agrc, char** argv){
    
      int fd = socket(AF_INET, SOCK_DGRAM, 0);
    
      int port = atoi(argv[1]);
      struct sockaddr_in addr;
      addr.sin_family = AF_INET;
      addr.sin_port = htons(port);
      addr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    
      
      bind(fd, (struct sockaddr*)&addr, sizeof(addr));
     
      struct ip_mreqn n;
      inet_pton(AF_INET, "239.0.0.10", &n.imr_multiaddr.s_addr);//组播地址
      inet_pton(AF_INET, "0.0.0.0", &n.imr_address.s_addr);//本机地址
      n.imr_ifindex = if_nametoindex("enp0s3");//本机的通信用的网卡的物理地址,可以用ifconfig查看
      
      int ret =  setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
    			&n, sizeof(n));
      
      struct sockaddr_in client;
      memset(&client, 0, sizeof(client));
      client.sin_family = AF_INET;
      client.sin_port = htons(6666);
      inet_pton(AF_INET, "239.0.0.10", &client.sin_addr.s_addr);
      
      int cnt = 0;
      while(1){
        char buf[64] = {0};
        sprintf(buf, "count=%d", cnt++);
        int ret = sendto(fd, buf, sizeof buf, 0, (struct sockaddr*)&client, sizeof(client));
        if(ret == -1){
          perror("sendto -1");
        }
        sleep(1);
      }
      
    }
    
    

    注意点:

    • 必须用setsockopt函数开通套接字的组播权限。发送端使用IPPROTO_IP和IP_MULTICAST_IF

    • 函数if_nametoindex的作用是通过网卡的名字,取得网卡的mac地址。

    组播接收端例子

    #include <sys/types.h> 
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <string.h>
    #include <net/if.h>
    
    int main(int agrc, char** argv){
    
      int fd = socket(AF_INET, SOCK_DGRAM, 0);
    
      struct sockaddr_in addr;
      memset(&addr, 0, sizeof(addr));
      addr.sin_family = AF_INET;
      addr.sin_port = htons(6666);
      //addr.sin_addr.s_addr = htons(INADDR_ANY);
      inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr.s_addr);
      socklen_t len = sizeof(addr);
    
      bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    
      struct ip_mreqn n;
      inet_pton(AF_INET, "239.0.0.10", &n.imr_multiaddr.s_addr);
      inet_pton(AF_INET, "0.0.0.0", &n.imr_address.s_addr);
      n.imr_ifindex = if_nametoindex("enp0s3");
      
      int ret =  setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
    			&n, sizeof(n));
      
      
      while(1){
        char buf[64] = {0};
        int ret = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
        write(STDOUT_FILENO, buf, ret);
        sleep(1);
      }
    }
    
    

    注意点:

    • 必须用setsockopt函数把接收端的套接字加入到组播的组里。接收端使用IPPROTO_IP和IP_ADD_MEMBERSHIP

    • 由于组播的时候,必须指定接收端的端口号,所以接收端必须调用bind函数,显示的指定自己用的端口号

    c/c++ 学习互助QQ群:877684253

    本人微信:xiaoshitou5854

  • 相关阅读:
    SharePoint 2013 图文开发系列之自定义字段
    SharePoint 2013 图文开发系列之Visual Studio 创建母版页
    SharePoint 2013 图文开发系列之代码定义列表
    SharePoint 2013 图文开发系列之计时器任务
    SharePoint 2013 图文开发系列之应用程序页
    SharePoint 2013 图文开发系列之事件接收器
    SharePoint 2013 图文开发系列之可视化WebPart
    SharePoint 2013 图文开发系列之WebPart
    SharePoint 2013 对二进制大型对象(BLOB)进行爬网
    SharePoint 2013 状态机工作流之日常报销示例
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/11115949.html
Copyright © 2011-2022 走看看