• 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

  • 相关阅读:
    idea语法检查红线隐藏配置
    spring security
    linux centos7下安装fastdfs
    定时任务在多个服务实例之间最多只执行一次
    C++11:01auto关键字
    chap3 数组 #C
    django之模型层 各种查询 数据库查询优化相关 事务使用
    django orm 中表与表之间建关系 视图层 路由层 django请求生命周期
    django 静态文件的配置 orm 中 字段与数据的增删改查 使用MySQL数据库
    BOM,DOM, JS,JQ
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/11115949.html
Copyright © 2020-2023  润新知