udp 广播通信

基于全网段广播的代码示例,要点主要有两个:
(1)设置socket属性SO_BROADCAST
(2)发送方添加广播255.255.255.255的路由,不然会产生“Network is unreachable”错误

ip route add 255.255.255.255 dev eth0

示例代码:


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

#define REMOTE_PORT 22222
#define LOCAL_PORT  55555

int main(int argc,char** argv)
{
    int ret = 0, opt = 1, recv_fd, send_fd;
    struct sockaddr_in local_addr, remote_addr;

    recv_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    send_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(recv_fd < 0 || send_fd < 0)
    {
        perror("create socket err");
        return -1;
    }

    ret = setsockopt(recv_fd,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(opt));
    if (ret)
    {
        perror("recv sock opt SO_BROADCAST err");
        return -2;
    }
    ret = setsockopt(recv_fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    if (ret)
    {
        perror("recv sock opt SO_REUSEADDR err");
        return -3;
    }
    ret = setsockopt(send_fd,SOL_SOCKET,SO_BROADCAST,&opt,sizeof(opt));
    if (ret)
    {
        perror("send sock opt SO_BROADCAST err");
        return -4;
    }

    memset(&local_addr, 0, sizeof(local_addr));
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(LOCAL_PORT);
    local_addr.sin_addr.s_addr = INADDR_ANY;

    memset(&remote_addr, 0, sizeof(remote_addr));
    remote_addr.sin_family = AF_INET;
    remote_addr.sin_port = htons(REMOTE_PORT);
    remote_addr.sin_addr.s_addr = inet_addr("255.255.255.255"); /* INADDR_BROADCAST */

    ret = bind(recv_fd,(struct sockaddr*)&local_addr,sizeof(local_addr));
    if(ret)
    {
        perror("recv sock bind err");
        return -4;
    }

    while(1)
    {
        struct sockaddr_in client_addr;
        socklen_t sock_len = sizeof(client_addr);
        char *ip =NULL;
        int port = 0;
        char buf[1024] = {0};

        /* receive */
        memset(&client_addr, 0, sizeof(struct sockaddr_in));
        client_addr.sin_family = AF_INET;
        int recv_len = recvfrom(recv_fd, buf, sizeof(buf), 0,
                            (struct sockaddr*)&client_addr, &sock_len);
        if (recv_len > 0)
        {
            ip = inet_ntoa(client_addr.sin_addr);
            port = ntohs(client_addr.sin_port);
            printf("recv from [%s][%d]: %s, len: %d\n", ip, port, buf, recv_len);
        }
        else
        {
            perror("recv err");
            continue;
        }

        /* send */
        int send_len = sendto(send_fd, buf, recv_len, 0,
                            (struct sockaddr*)&remote_addr,sizeof(remote_addr));
        if (send_len != recv_len)
        {
            perror("send err");
        }
        else
        {
            ip = inet_ntoa(remote_addr.sin_addr);
            port = ntohs(remote_addr.sin_port);
            printf("send  to  [%s][%d]: %s, len: %d\n", ip, port, buf, send_len);
        }
        // sleep(1);
    }

    close(recv_fd);
    close(send_fd);

    return 0;
}

posted @ 2024-07-18 11:34  坚持梦想的蜗牛  阅读(10)  评论(0编辑  收藏  举报