• 深入UDP收发数据(上)


    问题

    如何进行一对多的 UDP 数据发送?

    UDP 通信中的广播

    广播是向同一网络中的所有主机传输数据的方法

    广播类型

    • 直接广播: IP 地址中除网络地址外,其余主机地址均设置为1
    • 本地广播: 无须知道网络地址,255.255.255.255作为 IP 地址使用

    区别:

    • 本地广播数据不经过路由器寻址,直接发送到本地主机

    本地广播应用应用案例: DHCP

    DHCP (动态主机配置协议) 是一个局域网的网络协议 (基于 UDP 协议)

    • 本地主机可自动获取到服务器分配的 IP 地址和子网掩码

    DHCP 采用 客户端/服务器 模型,地址的动态分配由网络主机驱动

    工作方式:

    • 当 DHCP 服务器接收到来自网络主机的目标申请时,会向网络主机发送相关的地址配置信息,以实现网络主机地址信息的动态配置

    本地主机想要获取 IP 地址,首先会在本地广播一个数据包,源IP地址为0.0.0.0,目标IP地址为255.255.255.255,DHCP 服务器收到此数据包后,会回复本地主机;本地主机获取到的 IP 地址是有期限的,快到期限的时候,本地主机会继续广播,请求继续使用此 IP 地址。

    预备工作 => socket 属性设置 (option)

    socket 的本质是对本机网络资源的一种标识

    socket 本身有各种属性 (不同的连接,属性可能不同)

    通过 setsockopt() / getsockopt() 可存取指定 socket 的属性值

    socket 属性的改变可造成 socket 数据收发行为的改变

    TCP 编程中涉及的用法

    setsockopt() / getsockopt() 属性存取函数

    UDP 数据广播

    编程实验

    server.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. int main()
    7. {
    8. int server = 0;
    9. struct sockaddr_in addr = {0};
    10. struct sockaddr_in remote = {0};
    11. char buf[128] = "D.T.SoftWare\n";
    12. int len = 0;
    13. int brd = 1;
    14. addr.sin_family = AF_INET;
    15. addr.sin_addr.s_addr = htonl(INADDR_ANY);
    16. addr.sin_port = htons(8888);
    17. remote.sin_family = AF_INET;
    18. remote.sin_addr.s_addr = inet_addr("192.168.197.255");
    19. // remote.sin_addr.s_addr = 0xFFFFFFFF;
    20. remote.sin_port = htons(6666);
    21. server = socket(PF_INET, SOCK_DGRAM, 0);
    22. if(server < 0)
    23. {
    24. printf("server socket error\n");
    25. return -1;
    26. }
    27. if(bind(server, (struct sockaddr*)&addr, sizeof(addr)) == -1)
    28. {
    29. printf("udp server bind error\n");
    30. return -1;
    31. }
    32. setsockopt(server, SOL_SOCKET, SO_BROADCAST, &brd, sizeof(brd));
    33. printf("udp server start success!\n");
    34. while(1)
    35. {
    36. len = sizeof(remote);
    37. sendto(server, buf, strlen(buf), 0, (struct sockaddr*)&remote, len);
    38. sleep(1);
    39. }
    40. close(server);
    41. return 0;
    42. }

    client.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. int main()
    7. {
    8. int sock = 0;
    9. struct sockaddr_in remote = {0};
    10. struct sockaddr_in addr = {0};
    11. char buf[128] = {0};
    12. int r = 0;
    13. socklen_t len = 0;
    14. addr.sin_family = AF_INET;
    15. addr.sin_addr.s_addr = htonl(INADDR_ANY);
    16. addr.sin_port = htons(6666);
    17. if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    18. {
    19. printf("client socket error\n");
    20. return -1;
    21. }
    22. if(bind(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
    23. {
    24. printf("udp client bind errpr\n");
    25. return -1;
    26. }
    27. while(1)
    28. {
    29. len = sizeof(remote);
    30. r = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&remote, &len);
    31. if(r > 0)
    32. {
    33. buf[r] = 0;
    34. printf("Receive: %s\n", buf);
    35. }
    36. }
    37. close(sock);
    38. }

    192.168.197.xxx网段下的所有6666端口的进程都能够收到广播。

    思考

    UDP 是否还有其他一对多的数据发送方式? 

  • 相关阅读:
    为什么参与LiveVideoStackCon 2022 北京站
    matlab工具箱如何设置自己的BP神经网络初始权重
    操作系统——内存扩容:覆盖技术、交换技术(王道视频p44)
    R语言R包详解——stringr包:字符处理
    vscode electron安装环境
    MATLAB循环结构之while语句
    Pgsql 一个表中的字段like另一个表中的字段
    sass的常用语法总结
    Docker镜像的导入导出
    注入之SQLMAP(工具注入)
  • 原文地址:https://blog.csdn.net/qq_52484093/article/details/126294253