• 网络编程、广播、组播、数据库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. #include
    8. #include
    9. #include
    10. #include         /* See NOTES */
    11. #include
    12. #include
    13. #define N 64
    14. #define PORT 8888
    15. int main()
    16. {
    17.   int fd, val = 1;
    18.   if(-1 == (fd = socket(AF_INET, SOCK_DGRAM, 0))){
    19.       perror("socket");
    20.       exit(-1);
    21.   }
    22.   /*设置允许广播*/
    23.   if(-1 == setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(int))){
    24.       perror("setsockopt");
    25.       exit(-1);
    26.   }
    27.   /*设置接收方的IP和PORT*/
    28.   struct sockaddr_in sddr, cddr;
    29.   sddr.sin_family     = AF_INET;
    30.   sddr.sin_port       = htons(PORT);
    31.   sddr.sin_addr.s_addr = inet_addr("192.168.10.255");
    32.   char buf[N] = {0};
    33.   int len = sizeof cddr;
    34.   while(1){
    35.       printf("send> ");fflush(stdout);
    36.       fgets(buf, N, stdin);
    37.       if(-1 == sendto(fd, buf, N-1, 0, (void *)&sddr, sizeof(sddr))){
    38.           perror("sendto");
    39.           exit(-1);
    40.       }
    41.       if(0 == strncasecmp(buf, "quit", 4)){
    42.           break;
    43.       }
    44.       bzero(buf, N);
    45.       if(-1 == recvfrom(fd, buf, N, 0, (void *)&cddr, &len)){
    46.           perror("recvfrom");
    47.           exit(-1);
    48.       }
    49.       printf("recv> %s\n", buf);
    50.   }
    51.   close(fd);
    52. }

    三、组播(多播)

    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. #include
    8. #include
    9. #include
    10. #include         /* See NOTES */
    11. #include
    12. #include
    13. #include
    14. #define N 64
    15. #define RPORT 8888
    16. int main()
    17. {
    18. int fd = socket(AF_INET, SOCK_DGRAM, 0);
    19. if(-1 == fd){
    20.     perror("socket");
    21.     exit(-1);
    22. }
    23. /*填充ip_mreqn结构体*/
    24. struct ip_mreqn mreq;
    25. mreq.imr_multiaddr.s_addr = inet_addr("224.3.3.3");
    26. mreq.imr_address.s_addr   = inet_addr("0.0.0.0"); //
    27. mreq.imr_ifindex         = if_nametoindex("eth0");
    28. /*创建多播组*/
    29. if(-1 == setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq))){
    30.     perror("setsockopt");
    31.     exit(-1);
    32. }
    33. /*填充发送接收方IP和PORT*/
    34. struct sockaddr_in sddr;
    35. sddr.sin_family         = AF_INET;
    36. sddr.sin_port           = htons(RPORT); //RPORT is define :8888
    37. sddr.sin_addr.s_addr   = inet_addr("224.3.3.3"); //向多播组发送
    38. char buf[N] = {0};
    39. while(1){
    40.     printf("send> ");fflush(stdout);
    41.     fgets(buf, N, stdin);
    42.     if(-1 == sendto(fd, buf, N, 0, (void *)&sddr, sizeof(sddr))){
    43.         perror("sendto");
    44.         exit(-1);
    45.     }
    46.     if(!strncasecmp(buf, "quit", 4)){
    47.         break;
    48.     }
    49. }
    50. }

    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. #include
    8. #include
    9. #include
    10. #include         /* See NOTES */
    11. #include
    12. #include
    13. #include
    14. #define N 64
    15. #define RPORT 8888
    16. int main()
    17. {
    18. int fd = socket(AF_INET, SOCK_DGRAM, 0);
    19. if(-1 == fd){
    20.     perror("socket");
    21.     exit(-1);
    22. }
    23. /*填充ip_mreqn结构体*/
    24. struct ip_mreqn mreq;
    25. mreq.imr_multiaddr.s_addr = inet_addr("224.1.3.3");
    26. mreq.imr_address.s_addr   = inet_addr("0.0.0.0"); //
    27. mreq.imr_ifindex         = if_nametoindex("eth0");
    28. /*加入多播组*/
    29. if(-1 == setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))){
    30.     perror("setsockopt");
    31.     exit(-1);
    32. }
    33. /*填充发送接收方IP和PORT*/
    34. struct sockaddr_in sddr, cin;
    35. sddr.sin_family         = AF_INET;
    36. sddr.sin_port           = htons(RPORT); //RPORT is define :8888
    37. sddr.sin_addr.s_addr   = inet_addr("0.0.0.0");
    38. /*绑定自己的IP和PORT*/
    39. if(-1 == bind(fd, (void *)&sddr, sizeof(sddr))){
    40.     perror("bind");
    41.     exit(-1);
    42. }
    43. int len = sizeof cin;
    44. char buf[N] = {0};
    45. while(1){
    46.     if(-1 == recvfrom(fd, buf, N, 0, (void *)&cin, &len)){
    47.         perror("sendto");
    48.         exit(-1);
    49.     }
    50.     if(!strncasecmp(buf, "quit", 4)){
    51.         break;
    52.     }
    53.     printf("recv> %s", buf);
    54. }
    55. }

  • 相关阅读:
    支付系统 — 支付路由
    系统高可用需要关注的点
    Tomcat 9.0.54源码环境搭建
    Nwafu-OJ-1512 Problem 二分法解方程
    面经 | Go语言知识点
    leetcode_17电话号码的组合
    亲测解决np.fromiter转换list的时候出现cannot create object arrays from iterator
    CHATGPT它它它它它崩了~
    tomcat修改默认端口详细步骤(包含运行测试)
    SpringCloud(六) - RabbitMQ安装,三种消息发送模式,消息发送确认,消息消费确认(自动,手动)
  • 原文地址:https://blog.csdn.net/qq_52119661/article/details/132766737