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

  • 相关阅读:
    PAT 1008--------数组元素的循环右移,你需要记住的
    PAT1049-----枚举法,找规律题,注意降低时间复杂度
    PAT1048----你需要了解并记住的解题思路
    C++中几个输入函数的用法和区别(cin、cin.get()、cin.getline()、getline()、gets()、getchar()))
    PAT1040----关于数学题目的解法新思路值得借鉴,字符的配对
    PAT1029-----介绍字符串的解题思路和部分知识点
    PAT1027-----等差数列的问题或数学问题
    PAT1026----四舍五入的思路,%2d的一些知识
    / 已阅 /PAT1017-------高精度计算,问题的所有可能情况
    LeetCode 无重复字符的最长子串
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/11115949.html
Copyright © 2011-2022 走看看