局域网socket广播数据包

版权声明:本文为博主原创文章,转载请提提我 https://blog.csdn.net/hushiganghu/article/details/81279376

概述

在IPV4中报文的传输分为三种方式:单播,广播,多播

广播

本地广播: 地址就是255.255.255.255,它不经路由转发,发送本地网络下的所有主机,只能在局域网内转发,主要是不用知道目标主机的掩码与网络地址,本地转发同本地网络下的所有主机。

直接广播: 计算方法通过主机的掩码与网络地址计算出来。掩码最后为0的位为主机位。掩码与网络地址相与,然后主机位全变为1,就是直接广播地址。这样改网络地址下的所有主机都能接收到广播。

两者的区别就是,本地广播在不知道目标主机的网络地址下,如果目标主机是在本地网络,可以发送本地广播,本地网络下的所有主机都能接收广播。直接广播是目标主机的网络地址知道,那该网络地址网段下的所有主机都能收到广播,直接广播更精确范围更小些

多播

UDP Socket的使用过程:

  1. 初始化网络库

  2. 创建SOCK_DGRAM类型的Socket。

  3. 绑定套接字。

  4. 发送、接收数据。

  5. 销毁套接字。

  6. 释放网络库

发送者代码

send_brocast()
{
    int brd_socker = 0;
    int opt_bc_val = 1;
    int sendBytes = 0;
    //字符缓冲
//    char buff[30] = "ABCDEFGHUJKLMN";
    struct sockaddr_in broadcast_addr;//创建socket

    brd_socker = socket(PF_INET,SOCK_DGRAM,0);

    setsockopt(brd_socker, SOL_SOCKET, SO_BROADCAST, &opt_bc_val, sizeof(int));//UDP默认不支持广播,你需要打开,opt_bc_val = 1;

    /*设置接收者的参数*/
    memset(&broadcast_addr, 0, sizeof(struct sockaddr_in));
    broadcast_addr.sin_family = AF_INET;
    broadcast_addr.sin_addr.s_addr = INADDR_BROADCAST;//inet_addr("255.255.255.255");
    broadcast_addr.sin_port = htons(CAMERA_UDP_BROADCAST_PORT);
    bzero(&(broadcast_addr.sin_zero),8);

    /*发送数据*/
    if((sendBytes = sendto(brd_socker, buff, strlen(buff), 0, (struct sockaddr *)&broadcast_addr, sizeof(struct sockaddr))) == -1)
    {  
        close(brd_socker);
        printf("sendto fail, errno=%d\n", errno);  
        return -1;
    } 
    close(brd_socker);//关闭socket

    return 0;
}

接收者代码

recv_brocast()
{
    int str_len;
//    char buff[30];
    int iIndex = 0;
    int addr_len = sizeof(struct sockaddr_in);
    int receiver_socket;
    struct sockaddr_in receiver_addr;

    //初始化receiver_socket
    receiver_socket = socket(AF_INET,SOCK_DGRAM,0);
    memset(&receiver_addr,0,sizeof(receiver_addr));
    receiver_addr.sin_family = AF_INET;
    receiver_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    receiver_addr.sin_port = htons(CAMERA_UDP_BROADCAST_PORT);
    bzero(&(receiver_addr.sin_zero),8);

    //绑定地址
    if(bind(receiver_socket,(struct sockaddr *)&receiver_addr,sizeof(struct sockaddr_in)) == -1){
//        error_handling("bind() error");
        printf("ERROR\n");
        close(receiver_socket);
        perror("bind");
        return -1;
    }
printf("[%s]:%d\n",__FUNCTION__,__LINE__);

    /*接受数据 recv为单纯接收广播数据,而fecvfrom接收数据的同时获取广播者的IP地址*/
    str_len = recv(receiver_socket, (char*)buff, sizeof(buff), 0);
//  str_len = recvfrom(receiver_socket,buff,30-1,0,(struct sockaddr *)&receiver_addr, &addr_len);

        printf("str_len=%d\n", str_len);
        if(str_len < 0){
            perror("bind");
            return -1;//break;
        }
        buff[30 - 1] = 0;
        for(iIndex = 0; iIndex < str_len; iIndex++)
        {
            printf("%c", buff[iIndex]);
        }
        printf("\n");
//    }

    /*关闭socket*/
    close(receiver_socket);
    return 0;
}

参考网站

https://blog.csdn.net/z16304607/article/details/1439890
https://blog.csdn.net/sinat_20598829/article/details/39399999
https://blog.csdn.net/nlequalxf/article/details/51830960
https://www.cnblogs.com/zhangshenghui/p/6097497.html
https://blog.csdn.net/gufeijunchi/article/details/41519205

扫描二维码关注公众号,回复: 3533506 查看本文章

猜你喜欢

转载自blog.csdn.net/hushiganghu/article/details/81279376
今日推荐