• 网络编程、广播、组播、数据库sqlite3


    二、广播

    1、广播特点

    多点通讯 全网广播:255.255.255.255 容易造成网络风暴 子网广播:x.x.x.255 只允许数据报套接字操作 /*设置网络允许广播*/ int val = 1 setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(int));

    2、广播发送端流程

    1. 创建数据报(udp)套接字

    2. 设置套接字属性允许广播

    3. 设置接收方IP为广播地址

    4. 设置广播端口号

    5. 发送数据

    3、广播发送示例 ​

    1. /*========================================================
    2. * > 文 件 名 称: send.c
    3. * > 创  建 者: 清风徐来
    4. * > 邮    箱: zhangsl_cd@hqyj.com
    5. * > 创 建 时 间: 2020年08月24日 星期一 09时19分43秒
    6. ==========================================================*/
    7. ​
    8. #include
    9. #include
    10. #include
    11. #include         /* See NOTES */
    12. #include
    13. #include
    14. ​
    15. #define N 64
    16. #define PORT 8888
    17. int main()
    18. {
    19.   int fd, val = 1;
    20.   if(-1 == (fd = socket(AF_INET, SOCK_DGRAM, 0))){
    21.       perror("socket");
    22.       exit(-1);
    23.   }
    24. ​
    25.   /*设置允许广播*/
    26.   if(-1 == setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(int))){
    27.       perror("setsockopt");
    28.       exit(-1);
    29.   }
    30. ​
    31.   /*设置接收方的IP和PORT*/
    32.   struct sockaddr_in sddr, cddr;
    33.   sddr.sin_family     = AF_INET;
    34.   sddr.sin_port       = htons(PORT);
    35.   sddr.sin_addr.s_addr = inet_addr("192.168.10.255");
    36. ​
    37.   char buf[N] = {0};
    38.   int len = sizeof cddr;
    39.   while(1){
    40.       printf("send> ");fflush(stdout);
    41.       fgets(buf, N, stdin);
    42.       if(-1 == sendto(fd, buf, N-1, 0, (void *)&sddr, sizeof(sddr))){
    43.           perror("sendto");
    44.           exit(-1);
    45.       }
    46.       if(0 == strncasecmp(buf, "quit", 4)){
    47.           break;
    48.       }
    49.       bzero(buf, N);
    50.       if(-1 == recvfrom(fd, buf, N, 0, (void *)&cddr, &len)){
    51.           perror("recvfrom");
    52.           exit(-1);
    53.       }
    54.       printf("recv> %s\n", buf);
    55.   }
    56.   close(fd);
    57. }

    三、组播(多播)

    1、组播(多播)特点

    属于多点通讯。

    单播是一对一,广播是发送给所有主机,带宽占用大容易出现网络风暴,而多播是折中处理,只有加入多播组才能接收多播数据 组播IP:224.0.0.0 - 239.255.255.255 属于D类地址

    组播通信需要先创建多播组(发送方和接收方任意一方创建即可)

    创建/加入多播组,设置网络属性
        创建:IP_MULTICAST_IF
            struct ip_mreqn
            {
                struct in_addr imr_multiaddr; /* IP多点传送组地址 */
                struct in_addr imr_address; /* 本地接口的IP地址 */
                int imr_ifindex; /* 接口索引 */ //即网卡编号
            };
            imr_ifindex:
                #include 
                unsigned if_nametoindex(const char *ifname); //自动获取指定设备的索引号
        
        加入:IP_ADD_MEMBERSHIP
            struct ip_mreqn
            {
                struct in_addr imr_multiaddr; /* IP多点传送组地址 */
                struct in_addr imr_address; /* 本地接口的IP地址 */
                int imr_ifindex; /* 接口索引 */
            };
            imr_ifindex:
                #include 
                unsigned if_nametoindex(const char *ifname); //自动获取指定设备的索引号
    

    2、组播发送方流程

    1. 创建数据报套接字(udp)

    2. 接收方地址定为组播地址

    3. 设置端口号

    4. 发送数据

    3、组播发送方示例

    1. /*========================================================
    2. * > 文 件 名 称: send.c
    3. * > 创  建 者: 清风徐来
    4. * > 邮    箱: zhangsl_cd@hqyj.com
    5. * > 创 建 时 间: 2020年08月24日 星期一 10时35分12秒
    6. ==========================================================*/
    7. ​
    8. #include
    9. #include
    10. #include
    11. #include         /* See NOTES */
    12. #include
    13. #include
    14. ​
    15. #include
    16. ​
    17. #define N 64
    18. #define RPORT 8888
    19. ​
    20. int main()
    21. {
    22. int fd = socket(AF_INET, SOCK_DGRAM, 0);
    23. if(-1 == fd){
    24.     perror("socket");
    25.     exit(-1);
    26. }
    27. /*填充ip_mreqn结构体*/
    28. struct ip_mreqn mreq;
    29. mreq.imr_multiaddr.s_addr = inet_addr("224.3.3.3");
    30. mreq.imr_address.s_addr   = inet_addr("0.0.0.0"); //
    31. mreq.imr_ifindex         = if_nametoindex("eth0");
    32. /*创建多播组*/
    33. if(-1 == setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq))){
    34.     perror("setsockopt");
    35.     exit(-1);
    36. }
    37. ​
    38. /*填充发送接收方IP和PORT*/
    39. struct sockaddr_in sddr;
    40. sddr.sin_family         = AF_INET;
    41. sddr.sin_port           = htons(RPORT); //RPORT is define :8888
    42. sddr.sin_addr.s_addr   = inet_addr("224.3.3.3"); //向多播组发送
    43. ​
    44. char buf[N] = {0};
    45. while(1){
    46.     printf("send> ");fflush(stdout);
    47.     fgets(buf, N, stdin);
    48.     if(-1 == sendto(fd, buf, N, 0, (void *)&sddr, sizeof(sddr))){
    49.         perror("sendto");
    50.         exit(-1);
    51.     }
    52.     if(!strncasecmp(buf, "quit", 4)){
    53.         break;
    54.     }
    55. }
    56. }

    ​

    4、组播接收方流程

    1. 创建数据报套接字(udp)

    2. 加入多播组

    3. 绑定IP地址(加入组的组IP或"0.0.0.0")和端口号

    4. 等待接收数据

    5、组播接收方示例

    1. /*========================================================
    2. * > 文 件 名 称: send.c
    3. * > 创  建 者: 清风徐来
    4. * > 邮    箱: zhangsl_cd@hqyj.com
    5. * > 创 建 时 间: 2020年08月24日 星期一 10时35分12秒
    6. ==========================================================*/
    7. ​
    8. #include
    9. #include
    10. #include
    11. #include         /* See NOTES */
    12. #include
    13. #include
    14. ​
    15. #include
    16. ​
    17. #define N 64
    18. #define RPORT 8888
    19. ​
    20. int main()
    21. {
    22. int fd = socket(AF_INET, SOCK_DGRAM, 0);
    23. if(-1 == fd){
    24.     perror("socket");
    25.     exit(-1);
    26. }
    27. /*填充ip_mreqn结构体*/
    28. struct ip_mreqn mreq;
    29. mreq.imr_multiaddr.s_addr = inet_addr("224.1.3.3");
    30. mreq.imr_address.s_addr   = inet_addr("0.0.0.0"); //
    31. mreq.imr_ifindex         = if_nametoindex("eth0");
    32. /*加入多播组*/
    33. if(-1 == setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))){
    34.     perror("setsockopt");
    35.     exit(-1);
    36. }
    37. ​
    38. /*填充发送接收方IP和PORT*/
    39. struct sockaddr_in sddr, cin;
    40. sddr.sin_family         = AF_INET;
    41. sddr.sin_port           = htons(RPORT); //RPORT is define :8888
    42. sddr.sin_addr.s_addr   = inet_addr("0.0.0.0");
    43. ​
    44. /*绑定自己的IP和PORT*/
    45. if(-1 == bind(fd, (void *)&sddr, sizeof(sddr))){
    46.     perror("bind");
    47.     exit(-1);
    48. }
    49. ​
    50. int len = sizeof cin;
    51. char buf[N] = {0};
    52. while(1){
    53.     if(-1 == recvfrom(fd, buf, N, 0, (void *)&cin, &len)){
    54.         perror("sendto");
    55.         exit(-1);
    56.     }
    57.     if(!strncasecmp(buf, "quit", 4)){
    58.         break;
    59.     }
    60.     printf("recv> %s", buf);
    61. }
    62. }

  • 相关阅读:
    这7个AI软件让设计效率飞起,快来收藏 优漫动游
    BSP Day50
    正点原子嵌入式linux驱动开发——异步通知
    Docker从认识到实践再到底层原理(八)|Docker网络
    STL源码阅读小记(六)——Any
    烽火传递——单调队列优化dp问题
    「Nature领衔」8月BIOTREE成功助力发表文章17篇,总IF:190+!
    测试用例设计的底层逻辑
    使用 Filebeat+Easysearch+Console 打造日志管理平台
    Leetcode第 368 场周赛
  • 原文地址:https://blog.csdn.net/qq_52119661/article/details/132766737