栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

udp广播、组播

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

udp广播、组播

      广播组播

广播

发送端:

第一步、创建套接字socket()

第二部、设置为允许发送广播权限setsockopt()

第三步、向广播地址发送数据sendto()

接收端:(必须绑定0地址或者广播地址)

第一步、创建套接字socket()

第二部、绑定本机地址和套接字 bind()

第三步、等待接受广播数据recvfrom()

 

广播实例:

 发送者

 

//广播发送者代码实现

#include //printf

#include //exit

#include

#include //socket

#include //sockaddr_in

#include //htons inet_addr

#include //close

#include

 

int main(int argc, char const *argv[])

{

    if(argc < 3)

    {

        fprintf(stderr, "Usage: %s n", argv[0]);

        exit(1);

    }

 

    int sockfd; //文件描述符

    struct sockaddr_in broadcataddr; //服务器网络信息结构体

    socklen_t addrlen = sizeof(broadcataddr);

 

    //第一步:创建套接字

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

    {

        perror("fail to socket");

        exit(1);

    }

 

    //第二步:设置为允许发送广播权限

    int on = 1;

    if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)

    {

        perror("fail to setsockopt");

        exit(1);

    }

 

    //第三步:填充广播信息结构体

    broadcataddr.sin_family = AF_INET;

    broadcataddr.sin_addr.s_addr = inet_addr(argv[1]); //192.168.3.255 255.255.255.255

    broadcataddr.sin_port = htons(atoi(argv[2]));

 

    //第四步:进行通信

    char buf[128] = "";

    while(1)

    {

        fgets(buf, sizeof(buf), stdin);

        buf[strlen(buf) - 1] = '';

 

        if(sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&broadcataddr, addrlen) < 0)

        {

            perror("fail to sendto");

            exit(1);

        }

    }

 

    return 0;

}

接收者

 

//接收方代码实现

#include //printf

#include //exit

#include

#include //socket

#include //sockaddr_in

#include //htons inet_addr

#include //close

#include

 

int main(int argc, char const *argv[])

{

    if(argc < 3)

    {

        fprintf(stderr, "Usage: %s n", argv[0]);

        exit(1);

    }

 

    int sockfd; //文件描述符

    struct sockaddr_in broadcataddr; 

    socklen_t addrlen = sizeof(broadcataddr);

 

    //第一步:创建套接字

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

    {

        perror("fail to socket");

        exit(1);

    }

 

    //第二步:填充广播信息结构体

    broadcataddr.sin_family = AF_INET;

    broadcataddr.sin_addr.s_addr = inet_addr(argv[1]); //192.168.3.255 255.255.255.255

    broadcataddr.sin_port = htons(atoi(argv[2]));

 

    //第三步:将套接字与广播信息结构体绑定

    if(bind(sockfd, (struct sockaddr *)&broadcataddr, addrlen) < 0)

    {

        perror("fail to bind");

        exit(1);

    }

 

    //第四步:进行通信

    char text[32] = "";

    struct sockaddr_in sendaddr;

 

    while(1)

    {

        if(recvfrom(sockfd, text, sizeof(text), 0, (struct sockaddr *)&sendaddr, &addrlen) < 0)

        {

            perror("fail to recvfrom");

            exit(1);

        }

        

        printf("[%s - %d]: %sn", inet_ntoa(sendaddr.sin_addr), ntohs(sendaddr.sin_port), text);

    }

 

    return 0;

}

多播(又称组播)

多播概念:数据的收发只在同一分组中进行,所以多播又称组播

多播地址

ipv4的D类地址是多播地址

224.0.0.1~239.255.255.254

比起广播,多播具有可控性,只有加入多播组的接受者才能接受到信息

多播工作过程

 

 

多播编程流程:

发送者:

 

第一步:创建套接字 socket()

 

第二步:向多播地址发送数据 sendto()

 

接收者:

 

第一步:创建套接字 socket()

 

第二步:设置为加入多播组 setsockopt()

 

第三步:将套接字与多播信息结构体绑定 bind()

 

第五步:接收数据

多播地址结构体

 

setsockopt()

 

#include 

 

2 int setsockopt(int socket, int level, int option_name,

 

3  const void *option_value, socklen_t option_len);

 

4 功能:设置一个套接字的选项(属性)

 

5 参数:

 

6  socket:文件描述符

 

7  level:协议层次

 

8  IPPROTO_IP IP层次

 

9  option_name:选项的名称

 

10  IP_ADD_MEMBERSHIP 加入多播组

 

11  option_value:设置的选项的值

 

12  struct ip_mreq

 

13  {

 

14  struct in_addr imr_multiaddr; //组播ip地址

 

15  struct in_addr imr_interface; //主机地址

 

16  INADDR_ANY 任意主机地址(自动获取你的主机地址)

 

17  };

 

18  option_len:option_value的长度

 

19 返回值:

 

20  成功:0

 

21  失败:‐1

多播实例

发送端:

#include //printf

#include //exit

#include

#include //socket

#include //sockaddr_in

#include //htons inet_addr

#include //close

#include

 

int main(int argc, char const *argv[])

{

    if(argc < 3)

    {

        fprintf(stderr, "Usage: %s n", argv[0]);

        exit(1);

    }

 

    int sockfd; //文件描述符

    struct sockaddr_in groupcastaddr; //服务器网络信息结构体

    socklen_t addrlen = sizeof(groupcastaddr);

 

    //第一步:创建套接字

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

    {

        perror("fail to socket");

        exit(1);

    }

 

    //第二步:填充组播信息结构体

    groupcastaddr.sin_family = AF_INET;

    groupcastaddr.sin_addr.s_addr = inet_addr(argv[1]); //224.x.x.x - 239.x.x.x

    groupcastaddr.sin_port = htons(atoi(argv[2]));

 

    //第三步:进行通信

    char buf[128] = "";

    while(1)

    {

        fgets(buf, sizeof(buf), stdin);

        buf[strlen(buf) - 1] = ''; //"hellon"-->"hello"

 

        if(sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&groupcastaddr, addrlen) < 0)

        {

            perror("fail to sendto");

            exit(1);

        }

    }

 

    return 0;

}

接收端:

#include //printf

#include //exit

#include

#include //socket

#include //sockaddr_in

#include //htons inet_addr

#include //close

#include

 

int main(int argc, char const *argv[])

{

    if(argc < 3)

    {

        fprintf(stderr, "Usage: %s n", argv[0]);

        exit(1);

    }

 

    int sockfd; //文件描述符

    struct sockaddr_in groupcastaddr; 

    socklen_t addrlen = sizeof(groupcastaddr);

 

    //第一步:创建套接字

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

    {

        perror("fail to socket");

        exit(1);

    }

 

    //第二步:设置为加入多播组

    struct ip_mreq mreq;

    mreq.imr_multiaddr.s_addr = inet_addr(argv[1]);

    mreq.imr_interface.s_addr = INADDR_ANY;

    if(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)

    {

        perror("fail to setsockopt");

        exit(1);

    }

 

    //第三步:填充组播信息结构体

    groupcastaddr.sin_family = AF_INET;

    groupcastaddr.sin_addr.s_addr = inet_addr(argv[1]); //224.x.x.x - 239.x.x.x

    groupcastaddr.sin_port = htons(atoi(argv[2]));

 

    //第四步:将套接字与广播信息结构体绑定

    if(bind(sockfd, (struct sockaddr *)&groupcastaddr, addrlen) < 0)

    {

        perror("fail to bind");

        exit(1);

    }

 

    //第五步:进行通信

    char text[32] = "";

    struct sockaddr_in sendaddr;

 

    while(1)

    {

        if(recvfrom(sockfd, text, sizeof(text), 0, (struct sockaddr *)&sendaddr, &addrlen) < 0)

        {

            perror("fail to recvfrom");

            exit(1);

        }

        

        printf("[%s - %d]: %sn", inet_ntoa(sendaddr.sin_addr), ntohs(sendaddr.sin_port), text);

    }

 

    return 0;

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/882693.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号