Question: How to send one-to-many UDP data?

Broadcast in UDP communication

  • Broadcast is a method of transmitting data to all hosts in the same network
  • broadcast type

    • Direct broadcast: In addition to the network address in the IP address, all other host addresses are set to 1
    • Local broadcast: no need to know the network, use 255.255.255.255 as the IP address
  • the difference

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

Local Broadcast Use Case: DHCP

DHCP (Dynamic Host Configuration Protocol) is a LAN network protocol (based on UDP protocol)
  • The localhost can automatically obtain the IP address and subnet mask assigned by the server
DHCP uses a client/server model where the dynamic allocation of addresses is driven by network hosts
Way of working:
  • When the DHCP server receives the address request from the network host, it will send the relevant address configuration information to the network host to realize the dynamic configuration of the network host address information.

image.png

Preparation 👉 socket attribute setting (option)

  • The essence of socket is an identification of local network resources
  • The socket itself has various properties (different connections, properties may be different)
  • The attribute value of the specified socket can be accessed through setsockopt() / getsockopt()
  • The change of socket attributes can cause the change of socket data sending and receiving behavior

Design usage in TCP programming

image.png

setsockopt() / getsockopt() property access functions

 #include <sys/types.h>
#include <sys/socket.h>

int setsockopt(int sockfd, 
               int level, 
               int optname, 
               const void *optval, 
               socklen_t optlen);

int getsockopt(int sockfd,
               int level,
               int optname,
               void *optval,
               socklen_t *optlen);

若无错误发生返回 0; 否则返回 SOCKET_ERROR 错误。

UDP data broadcast

 int sock = socket(PF_INET, SOCK_DGRAM, 0);
int brd = 1;  // broadcast option flag

// ...
// ...

setsockopt(sock, SOL_SOCKET, SO_BROADCAST, 0, &brd, sizeof(brd));

Programming Experiment: UDP Data Broadcast

server.c
 #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main()
{
    int server = 0;
    struct sockaddr_in saddr = {0};
    int client = 0;
    struct sockaddr_in remote = {0};
    socklen_t asize = 0;
    int len = 0;
    char buf[32] = {0};
    int r = 0;

    server = socket(PF_INET, SOCK_DGRAM, 0);

    if (server == -1) {
        printf("server socket error");
        return -1;
    }

    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    saddr.sin_port = htons(8888);

    if (bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1) {
        printf("udp server bind error\n");
        return -1;
    }

    printf("udp server start sucess\n");

    while (1) {
        len = sizeof(remote);

        r = recvfrom(server, buf, sizeof(buf), 0, (struct sockaddr*)&remote, &len);

        if (r > 0) {
            buf[r] = 0;

            printf("Recvive: %s\n", buf);
        } else {
            break;
        }
    }

    close(server);

    return 0;
}
client.c
 #include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main()
{
    int sock = 0;
    struct sockaddr_in addr = {0};
    struct sockaddr_in remote = {0};
    socklen_t len = 0;
    char buf[128] = "D.T.Software";
    int r = 0;
    int brd = 1;

    sock = socket(PF_INET, SOCK_DGRAM, 0);

    if (sock == -1) {
        printf("socket error\n");
        return -1;
    }

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(7777);

    if (bind(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        printf("udp bind error\n");
        return -1;
    }

    remote.sin_family = AF_INET;
    remote.sin_addr.s_addr = 0xFFFFFFFF;
    // remote.sin_addr.s_addr = inet_addr("192.168.2.255");
    remote.sin_port = htons(8888);

    setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &brd, sizeof(brd));

    while (1) {
        len = sizeof(remote);

        r = strlen(buf);

        sendto(sock, buf, r, 0, (struct sockaddr*)&remote, len);

        sleep(1);
    }

    close(sock);

    return 0;
}
output:
 udp server start sucess
Recvive: D.T.Software
Recvive: D.T.Software

Thinking: Is there any other one-to-many data transmission method for UDP?


TianSong
734 声望138 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧