Linux——多播(组播)
作者:互联网
文章目录
多播(组播)组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。
224.0.0.0~224.0.0.255 为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
224.0.1.0~224.0.1.255 是公用组播地址,可以用于Internet;欲使用需申请。
224.0.2.0~238.255.255.255 为用户可用的组播地址(临时组地址),全网范围内有效;
239.0.0.0~239.255.255.255 为本地管理组播地址,仅在特定的本地范围内有效。
可使用ip ad命令查看网卡编号,如:
llycast$ ip ad
if_nametoindex 命令可以根据网卡名,获取网卡序号。
组播建立过程 组播结构图 代码server
/*************************************************************************
> File Name: server.c
> Author: 杨永利
> Mail: 1795018360@qq.com
> Created Time: 2020年10月28日 星期三 18时31分47秒
************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>
int main(int argc, char const *argv[])
{
// 创建套接字
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd == -1)
{
perror("socket error");
exit(1);
}
// 绑定server的iP和端口
struct sockaddr_in serv;
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(8787); // server端口
serv.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = bind(fd, (struct sockaddr*)&serv, sizeof(serv));
if(ret == -1)
{
perror("bind error");
exit(1);
}
// 初始化客户端地址信息
struct sockaddr_in client;
memset(&client, 0, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons(6767); // 客户端要绑定的端口 我懒了
// 给服务器开放组播权限
struct ip_mreqn flag;
// 使用组播地址给客户端发数据
inet_pton(AF_INET, "239.0.0.10", &client.sin_addr.s_addr);
inet_pton(AF_INET, "0.0.0.0", &flag.imr_address.s_addr); // 本地IP
flag.imr_ifindex = if_nametoindex("ens33");
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &flag, sizeof(flag));
// 开始通信
while(1)
{
// 一直给客户端发数据
static int num = 0;
char buf[1024] = {0};
sprintf(buf, "hello, udp == %d\n", num++);
int ret = sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr*)&client, sizeof(client));
if(ret == -1)
{
perror("sendto error");
break;
}
printf("server == send buf: %s\n", buf);
sleep(1);
}
close(fd);
return 0;
}
client
/*************************************************************************
> File Name: client.c
> Author: 杨永利
> Mail: 1795018360@qq.com
> Created Time: 2020年10月28日 星期三 18时47分21秒
************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>
int main(int argc, const char* argv[])
{
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd == -1)
{
perror("socket error");
exit(1);
}
// 绑定iP和端口
struct sockaddr_in client;
memset(&client, 0, sizeof(client));
client.sin_family = AF_INET;
client.sin_port = htons(6767); // ........
inet_pton(AF_INET, "0.0.0.0", &client.sin_addr.s_addr);
int ret = bind(fd, (struct sockaddr*)&client, sizeof(client));
if(ret == -1)
{
perror("bind error");
exit(1);
}
// 加入到组播地址
struct ip_mreqn fl;
inet_pton(AF_INET, "239.0.0.10", &fl.imr_multiaddr.s_addr);
inet_pton(AF_INET, "0.0.0.0", &fl.imr_address.s_addr);
fl.imr_ifindex = if_nametoindex("ens33");
setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &fl, sizeof(fl));
// 接收数据
while(1)
{
char buf[1024] = {0};
int len = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
if(len == -1)
{
perror("recvfrom error");
break;
}
printf("client == recv buf: %s\n", buf);
}
close(fd);
return 0;
}
标签:多播,组播,int,client,fd,Linux,include,buf 来源: https://blog.51cto.com/u_15265965/2892050