Linux网络编程之多播

合集下载

LINUX下多路径(multi-path)介绍及使用

LINUX下多路径(multi-path)介绍及使用

LINUX下多路径(multi-path)介绍及使用一、什么是多路径普通的电脑主机都是一个硬盘挂接到一个总线上,这里是一对一的关系。

而到了有光纤组成的SAN环境,或者由iSCSI组成的IPSAN环境,由于主机和存储通过了光纤交换机或者多块网卡及IP来连接,这样的话,就构成了多对多的关系。

也就是说,主机到存储可以有多条路径可以选择。

主机到存储之间的IO由多条路径可以选择。

每个主机到所对应的存储可以经过几条不同的路径,如果是同时使用的话,I/O流量如何分配?其中一条路径坏掉了,如何处理?还有在操作系统的角度来看,每条路径,操作系统会认为是一个实际存在的物理盘,但实际上只是通向同一个物理盘的不同路径而已,这样是在使用的时候,就给用户带来了困惑。

多路径软件就是为了解决上面的问题应运而生的。

多路径的主要功能就是和存储设备一起配合实现如下功能:1.故障的切换和恢复2.IO流量的负载均衡3.磁盘的虚拟化由于多路径软件是需要和存储在一起配合使用的,不同的厂商基于不同的操作系统,都提供了不同的版本。

并且有的厂商,软件和硬件也不是一起卖的,如果要使用多路径软件的话,可能还需要向厂商购买license才行。

比如EMC公司基于linux下的多路径软件,就需要单独的购买license。

好在, RedHat和Suse的2.6的内核中都自带了免费的多路径软件包,并且可以免费使用,同时也是一个比较通用的包,可以支持大多数存储厂商的设备,即使是一些不是出名的厂商,通过对配置文件进行稍作修改,也是可以支持并运行的很好的。

二、Linux下multipath介绍,需要以下工具包:在CentOS 5中,最小安装系统时multipath已经被安装,查看multipath是否安装如下:1、device-mapper-multipath:即multipath-tools。

主要提供multipathd和multipath 等工具和 multipath.conf等配置文件。

linux多线程编程详解教程(线程通过信号量实现通信代码)

linux多线程编程详解教程(线程通过信号量实现通信代码)

linux多线程编程详解教程(线程通过信号量实现通信代码)线程按照其调度者可以分为⽤户级线程和核⼼级线程两种。

(1)⽤户级线程主要解决的是上下⽂切换的问题,它的调度算法和调度过程全部由⽤户⾃⾏选择决定,在运⾏时不需要特定的内核⽀持。

在这⾥,操作系统往往会提供⼀个⽤户空间的线程库,该线程库提供了线程的创建、调度、撤销等功能,⽽内核仍然仅对进程进⾏管理。

如果⼀个进程中的某⼀个线程调⽤了⼀个阻塞的系统调⽤,那么该进程包括该进程中的其他所有线程也同时被阻塞。

这种⽤户级线程的主要缺点是在⼀个进程中的多个线程的调度中⽆法发挥多处理器的优势。

(2)这种线程允许不同进程中的线程按照同⼀相对优先调度⽅法进⾏调度,这样就可以发挥多处理器的并发优势。

现在⼤多数系统都采⽤⽤户级线程与核⼼级线程并存的⽅法。

⼀个⽤户级线程可以对应⼀个或⼏个核⼼级线程,也就是“⼀对⼀”或“多对⼀”模型。

这样既可满⾜多处理机系统的需要,也可以最⼤限度地减少调度开销。

Linux的线程实现是在核外进⾏的,核内提供的是创建进程的接⼝do_fork()。

内核提供了两个系统调⽤clone()和fork(),最终都⽤不同的参数调⽤do_fork()核内API。

当然,要想实现线程,没有核⼼对多进程(其实是轻量级进程)共享数据段的⽀持是不⾏的,因此,do_fork()提供了很多参数,包括CLONE_VM(共享内存空间)、CLONE_FS(共享⽂件系统信息)、CLONE_FILES(共享⽂件描述符表)、CLONE_SIGHAND(共享信号句柄表)和CLONE_PID(共享进程ID,仅对核内进程,即0号进程有效)。

当使⽤fork系统调⽤时,内核调⽤do_fork()不使⽤任何共享属性,进程拥有独⽴的运⾏环境,⽽使⽤pthread_create()来创建线程时,则最终设置了所有这些属性来调⽤__clone(),⽽这些参数⼜全部传给核内的do_fork(),从⽽创建的“进程”拥有共享的运⾏环境,只有栈是独⽴的,由__clone()传⼊。

广播与多播

广播与多播

Linux ƒ训 ƒ训 ƒ
多播的用途
Linux ƒ训 ƒ训 ƒ
单播和广播是两个极端,要么一个,要么全部。 多播提供一种折衷方案,多播数据报仅由对该数据报感兴 趣的接口接收。 广播一般局限于局域网。 而多播既可以用于局域网也可以跨越广域网。
加入多播组
Linux ƒ训 ƒ训 ƒ
主机要接收多播数据必须预先加入多播组。 IP多播组由特定IP地址来区分。 进程通过把UDP套接字(SOCK_DGRAM类型)绑定到一个 多播组的IP地址,并设置相应的套接字选项,就可以加入 这个多播组。 设置套接字选项通知网络接口该多播地址上到来的消息应 该被传送给这个套接字。 如果同一台机器上有多个进程加入该组,则网络接口会把 每个消息复制给所有这些进程。
受限广播地址
– – –
链路层广播地址
MAC地址全1的地址,即FF:FF:FF:FF:FF:FF。 – 带有这样目的MAC地址的帧经过任何该子网上的主机时,都会被其链路层 接收。 – ARP就是利用这个地址发出广播来确定具有指定IP地址对应主机的MAC 地址。

广播过程
Linux ƒ训 ƒ训 ƒ
sendto 目的IP=128.7.6.255 目的端口=5000 发送应用进程 接收应用进程 | | 端口=5000 | | | | UDP层 协议= UDP UDP 层-->丢弃 协议= UDP UDP层 | | | | IPV4层 帧类型=0800 IPV4层 帧类型=0800 IPV4层 |_ __| | | 数据链路层 数据链路层 数据链路层 | 00:04:ac:17:bf:38 | 00:0a:95:87:bc:55 | | | | _______ |____________________ |_______________________ |_________ 子网128.7.6 | host1 | host2 <---以太网头 | IPV4头 | UDP头 | UDP数据------MAC=ff:ff:ff:ff:ff:ff 目的IP=128.7.6.255 目的端口=5000 类型=0800 协议=UDP

linux多播技术介绍与参数选项说明

linux多播技术介绍与参数选项说明

linux多播技术介绍与参数选项说明多播,也称为“组播”,将网络中同一业务类型主机进行了逻辑上的分组,进行数据收发的时候其数据仅仅在同一分组中进行,其他的主机没有加入此分组不能收发对应的数据。

在广域网上广播的时候,其中的交换机和路由器只向需要获取数据的主机复制并转发数据。

主机可以向路由器请求加入或退出某个组,网络中的路由器和交换机有选择地复制并传输数据,将数据仅仅传输给组内的主机。

多播的这种功能,可以一次将数据发送到多个主机,又能保证不影响其他不需要(未加入组)的主机的其他通信。

相对于传统的一对一的单播,多播具有如下的优点:q 具有同种业务的主机加入同一数据流,共享同一通道,节省了带宽和服务器的优点,具有广播的优点而又没有广播所需要的带宽。

q 服务器的总带宽不受客户端带宽的限制。

由于组播协议由接收者的需求来确定是否进行数据流的转发,所以服务器端的带宽是常量,与客户端的数量无关。

q 与单播一样,多播是允许在广域网即Internet上进行传输的,而广播仅仅在同一局域网上才能进行。

组播的缺点:q 多播与单播相比没有纠错机制,当发生错误的时候难以弥补,但是可以在应用层来实现此种功能。

q 多播的网络支持存在缺陷,需要路由器及网络协议栈的支持。

多播的应用主要有网上视频、网上会议等。

二,广域网的多播多播的地址是特定的,D类地址用于多播。

D类IP地址就是多播IP地址,即224.0.0.0至239.255.255.255之间的IP地址,并被划分为局部连接多播地址、预留多播地址和管理权限多播地址3类:q 局部多播地址:在224.0.0.0~224.0.0.255之间,这是为路由协议和其他用途保留的地址,路由器并不转发属于此范围的IP包。

q 预留多播地址:在224.0.1.0~238.255.255.255之间,可用于全球范围(如Internet)或网络协议。

q 管理权限多播地址:在239.0.0.0~239.255.255.255之间,可供组织内部使用,类似于私有IP地址,不能用于Internet,可限制多播范围。

高级计算机网络-多播

高级计算机网络-多播

2019/9/16
16
密集模式
密集模式假设多播组的成员密集分布在网络中, 每个子网至少含一个成员。密集模式还需要充足的带 宽。DVMRP, MOSPF和PIM-DM都是密集模式路由选择协 议。密集模式路由选择协议依靠扩散(flooding)技 术把信息传播到整个网络的路由器上。
2019/9/16
2019/9/16
10
共享树(shared tree)
共享树方法中使用一个中央多播路由器,有时候又称 为核心路由器。需要进行多播的源结点将他们所要传 递的信息包都传给这个核心路由器,然后由这个核心 路由器通过一棵共享树将信息包一个一个的传给组中 的每一个接收结点。每个组中只要建立一棵共享树就 可以了,而不是象在SRSPT中需要为组中的每个源结 点建立一棵树。与SRSPT算法相比,共享树对路由器 和网络带宽(bandwidth)的需求更小。在CBT和PIM 协议中使用共享树的思想来传递信息包。
IP 多 播 的 最 早 实 施 方 案 依 赖 于 传 统 的 竭 尽 全 力 方 法 和 User Datagran Protoco1,但它们不能保证多播数据流的可靠传输。
2019/9/16
8
2 IP 多播协议
HP的Internet群管JF协议(LGMP)
Protocol Independent Mu1ticast、
• 在每层上如何对各组编址 • 在IP层以上的各层是否需要标识组,如果需要,怎样标识? 4. 方向性: • 一对多 或者 多对多 • 转送者是否是接受者的一个子集?
2019/9/16
5
1 概述
推进
发送者
ISP
图 6.1 对于分散在 Internet 中的主机多播

Linux下IGMP以及多播路由分析

Linux下IGMP以及多播路由分析

Linux下IGMP以及多播路由分析(转载)最近在做多播这块,顺带研究了一下Linux Kernel对IGMPv3以及多播路由的支持.先简单介绍IGMPv3,一个网络协议总的说来无非多是"一问,一答",当然也有主动的去"报告",IGMPv3也不例外.1.看过IGMPv2以及v1的人会奇怪为什么要v3,v3能带来些什么?1>.IGMPv2/v1是典型的接受任意源多播(Any-Source Multicast)[ASM],即它只是关注多播组,而不关注是谁发送的,这样会有一些问题,比如说,假如一个局域网存在一个多播视频服务器,其它Host在上面点播视频;假如出现一个伪装者,也向这个多播组发送干扰数据,但Host无法辨别,这样可能引起视频的接受断断续续,影响服务的提供,显然这不是很理想;而IGMPv3的提出,就是为了解决这个问题,它提出了源特定多播(Source-Specific Multicast)[SSM],不仅关注多播组,也关注发送多播组的源.2>.包的类型IGMPv3主要有两种包:Type Number (hex) Message Name----------------- ------------0x11 Membership Query0x22 Version 3 Membership Report基于兼容的原因,还有IGMPv2/v1的几种包:0x12 Version 1 Membership Report [RFC-1112] 0x16 Version 2 Membership Report [RFC-2236] 0x17 Version 2 Leave Group [RFC-2236] 关于协议部分更详尽的细节,参考RFC3376(IGMPv3),RFC2236(IGMPv2),RFC1112(IGMPv1)2.Linux Kernel的IGMPv3以及多播路由的实现仔细看了这部分的代码,主要的文件比较少,分别为:igmp.c 内核实现的对IGMP的实现,可以兼容v2/c.ipmr.c 看文件名自然就可以猜测是多播路由的实现.其中,值得参考的文档是Sprint Labs的两份文档,一份是实现架构,一份是测试计划,不过从我读Code来看,这两份文档只具备参考意义,因为kernel的实现并不是按照其实现架构文档来实现的,看igmp.c/ipmr.c的文件注释可以知道多播部分的实现是其它人来实现的,并不遵循该设计文档(也许该实验室是准备实现的,但最终由于某些其它原因由其它人来实现,并且没有采取其设计文档),不过设计思想值得参考,实际的实现比那份设计文档要简洁一些.下面看看一些具体的数据结构,由于部分成员我也没看懂做什么用处,如果你知道,请告诉我:)net_device{}--------| |<------------------|~~~~~~~~| in_device{} ||--------| --------- || ip_ptr |--->| dev |----|--------| |---------|<------------------| | |~~~~~~~~~| ip_mc_list{} ||~~~~~~~~| |---------| --------- |-------- | mc_list |--->|interface|----|---------| |---------||~~~~~~~~~| |multiaddr|--------- |---------||~~~~~~~~~|---------通过上图可以看到3个结构之间的部分关系,我简单说说这三个结构:net_device:针对每个网络设备的一个抽象,比如你用ifconfig看到的eth0,就对应了一个该结构实例.in_device:针对IPv4的网络部分的描诉,因为Linux支持不仅仅是TCP/IP协议族,还用ATM等等,其底层设备是不同的,而对与网络设备的通用部分,用net_device{}描述,而针对不同协议私有部分,则使用不同结构,支持IPv4的设备,就使用该结构.ip_mc_list:描述的自然是IP设备的多播相关信息,我只花出了一个multiaddr,举例说来,我们说"eth0加入了多播组224.0.0.1",multiaddr就记录了该设备加入的一个多播组:224.0.0.1因此,结合上图,可以基本知道一个网络设备,如何记录它加入的多播组.下面来看igmp的处理流程:--------|ip_rcv()|[IP层的总入口]--------|V------------------|ip_local_deliver()|[本地分发,即目的地为本地]------------------|V----------|igmp_rcv()|[分发到IGMP的处理入口] ----------|V------------------------| [处理查询] |[处理报告]V V------------------ -------------------|igmp_heard_query()| |igmp_heard_report()|------------------ -------------------[开始计时器]| ++++++++++++++ |[停止计时器]----> +ip_mc_list{}+<----++++++++++++++|V------------------|igmp_send_report()|------------------在上面的文档里简要介绍了kernel对IGMP包的处理,其实下面才是重点,kernel 怎么处理多播包呢?即多播包怎么路由呢?这又涉及到UNIX常用的一个哲学"数据路径要分离于控制路径(最常见的说法是策略与机制,上面的说法是我自己理解后表述的,因为我老把这两者弄反,呵呵:))",这实际上是两个分离的问题:1).多播包在内核中怎么样被处理?2).该使用什么方法在应用程序中向内核添加路由?说道这里,我再次强调一下,注意区分在网路中的常见角色"Host"和"Router",时刻记得它们本质的区别是重要的:),它们最重要的区别在于是否能够转发包.好了,我们来依次解决上面的两个问题:我们不去考虑MAC层对多播的处理,只是理解就可以了,记得网络设备在MAC层可以实现一个不完全的过滤就可以了,相关知识,参考<TCP/IP详解>卷一,下面我们从IP层开始考虑(认为网卡支持多播,不过现在不支持多播的网卡很少了,呵呵)1>.多播包在kernel的处理流程自然,还是从ip_rcv()起步:),呵呵.##################################################################### ######--------|ip_rcv()|[IP层的总入口]--------|[单播的路由查找入口] V--------------------- ----------------|ip_route_input_slow()|<--|ip_route_input()|[路由查找总入口]--------------------- ----------------|[本地分发] V------------------- -------------------|ip_local_deliver() |<--|ip_route_input_mc()|[多播路由查找入口] ------------------- -------------------|V ***------------- *K*[在MFC中查找] |ip_mr_input()|[多播路由查找入口] *E*++++++++++++++++++ ------------- *R*+Multicast Forwar+------------->| *N*+ding Cache +<-------------V *E*++++++++++++++++++ --------------- *L*^ | |ip_mr_forward()|[根据找到的多播路由转发] ***| | --------------- || | V===================================================================== ======| V ^------------------- ||iset/getsocketopt()|[在应用层添加/删除多播路由] ***------------------- *A**P**P****##################################################################### ####上面是一个简要的流程,下面来稍微具体的谈谈:首先还是以关键的数据结构为开始:(给我看你的流程图而藏起你的表,我将仍然是莫名其妙。

Linux多任务多线程编程-

Linux多任务多线程编程-
23
等待进程结束
当一个进程正常或异常终止时,内核就向其父进程发 送SIGCHLD信号。
Linux系统提供了waitid()函数,他们的作用是等待另外 一个进程的结束。函数定义如下: #include <sys/types.h> #include <sys/wait.h> pid_t waitpid(pid_t pid, int *statloc, int options) ; 两个函数返回:若成功则为进程I D,若出错则为-1
3
(1)进程级多任务
在对话中可以并发激活多个进程,这些进程相 互合作来完成一个最终目标。
所有的进程共享CPU运行,一个进程运行一段 时间,然后另一个进程再运行一段时间。
操作系统控制进程之间的转换,直到所有的进
程运行完成。对于这样一种多个进程并发执行 的多任务实现方式,称作进程级多任务。
4
什么是进程?
if (-1==pid)
{
// 检查是否创建成功
printf("Error to create new process!\n");
return 0;
}
else if (pid==0)
{
// 子进程
printf("Child process!\n");
} else
{
// 父进程
printf("Parent process! Child process ID: %d\n", pid);
}
return 0;
}
20
fork出错的原因
系统中已经有了太多的进程
该实际用户I D的进程总数超过了系统限 制
CHILD_MAX规定了每个实际用户I D在任一 时刻可具有的最大进程

Linux网络编程怎么使用多进程实现服务器并发访问

Linux网络编程怎么使用多进程实现服务器并发访问

Linux网络编程怎么使用多进程实现服务器并发访问今天就有读者问小编我了,Linux网络编程怎么使用多进程实现服务器并发访问?然后小编我通过查阅相关资料后,就把相关的解决方法分享到这里吧,以下就是具体内容:采用多进程的方式实现服务器的并发访问的经典范例。

程序实现功能:1.客户端从标准输入读入一行文字,发送到服务器.2.服务器接收到客户端发来的文字后,原样返回给客户端.3.客户端接收到服务器的发来的文字后,输出到标准输出,然后继续以上步骤。

服务器端过程:建立好监听套接字后,等待客户端的连接,接收到一个连接后,创建一个子进程来与客户端进行通信,主进程则继续等待其他客户端的连接。

代码如下:#include#include#include#include#include#include#include#include#include#define SERV_PORT 1113 #define LISTENQ 32#define MAXLINE 1024/***连接处理函数***/void str_echo(int fd);intmain(int argc, char *argv[]){int listenfd,connfd;pid_t childpid;socklen_t clilen;struct sockaddr_in servaddr;struct sockaddr_in cliaddr;if((listenfd = socket(AF_INET, SOCK_STREAM,0))==-1){error:%s\n\a&quot;,strerror(errno));exit(1);}/* 服务器端填充sockaddr结构*/bzero(&amp;servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl (INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);/* 捆绑listenfd描述符*/if(bind(listenfd,(struct sockaddr*)(&amp;servaddr),sizeof(struct sockaddr))==-1){error:%s\n\a&quot;,strerror(errno));exit(1);}/* 监听listenfd描述符*/if(listen(listenfd,5)==-1){fprintf(stderr,&quot;Listen error:%s\n\a&quot;,strerror(errno));exit(1);}for ( ; ; ) {clilen = sizeof(cliaddr);/* 服务器阻塞,直到客户程序建立连接*/if((connfd=accept(listenfd,(struct sockaddr*)(&amp;cliaddr),&amp;clilen))==-1){fprintf(stderr,&quot;Accept error:%s\n\a&quot;,strerror(errno));exit(1);}//有客户端建立了连接后if ( (childpid = fork()) == 0) { /*子进程*/close(listenfd); /* 关闭监听套接字*/str_echo(connfd); /*处理该客户端的请求*/exit (0);}close(connfd);/*父进程关闭连接套接字,继续等待其他连接的到来*/}}void str_echo(int sockfd){ssize_t n;char buf[MAXLINE];again:while ( (n = read(sockfd, buf, MAXLINE)) &gt; 0)write(sockfd, buf, n);if (n &lt; 0 &amp;&amp; errno == EINTR)//被中断,重入goto again;else if (n &lt; 0){//出错fprintf(stderr,&quot;read error:%s\n\a&quot;,strerror(errno));exit(1);}}客户端过程:创建连接套接字,主动向服务器发起连接请求,建立连接后,等待标准输入,输入完成后,将输入的内容发送给服务器,接着接收服务器发送过来的内容,并将接收到的内容输出到标准输出。

Linux网络的多播IP技术

Linux网络的多播IP技术
/htmldata/2005_05/1/3/article_1201_1.html 3 5 [2009-1-6 22:46:30]
Unixபைடு நூலகம்
- Linux

IP

} /* 单 开 进 测试 IP */ loop = 1; if(setsockopt(socket_descriptor, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) { perror("setsockopt:IP_MULTICAST_LOOP"); exit(EXIT_FAILURE); } /* 组 进 诉Linux内 将 数 */ command.imr_multiaddr.s_addr = inet_addr("224.0.0.1"); command.imr_interface.s_addr = htonl(INADDR_ANY); if(command.imr_multiaddr.s_addr == -1) { perror("224.0.0.1 not a legal multicast address"); exit(EXIT_FAILURE); } if (setsockopt(socket_descriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command, sizeof(command)) < 0) { perror("setsockopt:IP_ADD_MEMBERSHIP"); } while(iter++ < 8) { sin_len = sizeof(sin); if(recvfrom(socket_descriptor, message, 256, 0, (struct sockaddr *)&sin, &sin_len) == -1) { perror("recvfrom"); } printf("Response #%-2d from server: %s\n", iter, message); sleep(2); } /* 8 */ if(setsockopt(socket_descriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP, &command, sizeof(command)) < 0) { perror("setsockopt:IP_DROP_MEMBERSHIP"); } close(socket_descriptor); exit(EXIT_SUCCESS);}

linux多线程和多进程详解

linux多线程和多进程详解

linux下多进程、多线程编程linux下进程(一)理解Linux下进程的结构Linux下一个进程在内存里有三部份的数据,就是“数据段”,“堆栈段”和“代码段”,其实学过汇编语言的人一定知道,一般的CPU象I386,都有上述三种段寄存器,以方便操作系统的运行。

“代码段”,顾名思义,就是存放了程序代码的数据,假如机器中有数个进程运行相同的一个程序,那么它们就可以使用同一个代码段。

堆栈段存放的就是子程序的返回地址、子程序的参数以及程序的局部变量。

而数据段则存放程序的全局变量,常数以及动态数据分配的数据空间(比如用malloc之类的函数取得的空间)。

这其中有许多细节问题,这里限于篇幅就不多介绍了。

系统如果同时运行数个相同的程序,它们之间就不能使用同一个堆栈段和数据段。

(二)如何使用fork在Linux下产生新的进程的系统调用就是fork函数,这个函数名是英文中“分叉”的意思。

为什么取这个名字呢?因为一个进程在运行中,如果使用了fork,就产生了另一个进程,于是进程就“分叉”了,所以这个名字取得很形象。

下面就看看如何具体使用fork,这段程序演示了使用fork的基本框架:void main(){int i;if ( fork() == 0 ) {/* 子进程程序*/for ( i = 1; i " );fgets( command, 256, stdin );command[strlen(command)-1] = 0;if ( fork() == 0 ) {/* 子进程执行此命令*/execlp( command, command );/* 如果exec函数返回,表明没有正常执行命令,打印错误信息*/perror( command );exit( errorno );}else {/* 父进程,等待子进程结束,并打印子进程的返回值*/wait ( &rtn );printf( " child process return %d\n",. rtn );}}}此程序从终端读入命令并执行之,执行完成后,父进程继续等待从终端读入命令。

实验十二高级套接字(广播、多播)

实验十二高级套接字(广播、多播)

多播地址
多播地址是用来标识 多播组的IP地址。
IPv4中,多播地址范 围是224.0.0.0到 239.255.255.255。
一个多播组可以包含 多个设备,它们通过 共享相同的多播地址 进行通信。
多播套接字编程示例
01
创建多播套接字
使用`socket()`函数创建一个套接字,并使用 `setsockopt()`函数设置套接字为多播模式。
广播套接字编程示例
```
其中,broadcastaddr是一个包含广 播地址的sockaddr结构体。
04
多播套接字
多播概述
多播是一种允许一台或多台设 备发送一条消息到多个设备的 技术。
它常用于实时通信、在线游戏、 视频会议等场景。
与单播通信(一对一通信)相 比,多播通信(一对多通信) 可以更有效地利用网络资源。
05
实验步骤与实现
实验环境与准备
操作系统
Linux或类Unix系统,因为广播和多播套接字在这些 系统上支持较好。
开发环境
安装C语言开发环境,包括编译器、调试器等。
套接字库
熟悉套接字编程,了解TCP/IP协议栈。
广播套字实现
01
创建套接字
02
绑定地址
03 配置广播选项
04
发送广播消息
接收广播消息
在实验过程中,我遇到了许多预料之外的问题和挑战,通过不断尝试和查阅资料,我学会 了如何分析和解决这些问题。
高级套接字的应用前景
实时通信
高级套接字可以实现高效的广 播和多播通信,使得实时通信 更加可靠和高效。在视频会议 、在线游戏、远程教育等领域 有着广泛的应用前景。
分布式系统
高级套接字可以用于构建分布 式系统,实现不同节点之间的 快速通信和数据交换。在云计 算、物联网、大数据等领域有 着重要的应用价值。

linux igmp使用

linux igmp使用

linux igmp使用IGMP(Internet Group Management Protocol,互联网组管理协议)是一个网络协议,它允许主机加入或离开一个多播组,并且可以通过路由器转发多播数据包到需要的主机。

在Linux系统中,我们可以使用IGMP协议来管理多播组。

在本篇文章中,我们将逐步探讨Linux系统中如何使用IGMP协议,并详细说明每个步骤。

第一步:了解IGMP协议IGMP是一种用于IPv4网络的协议,它允许主机加入或离开一个多播组。

当主机需要接收特定多播组的数据时,它会发送IGMP报文请求加入该组。

当主机不再需要接收该组的数据时,它会发送IGMP报文离开该组。

路由器会根据主机发送的IGMP报文来判断如何转发多播数据包。

第二步:安装IGMP软件包在大多数Linux发行版中,默认已经安装了IGMP软件包。

如果你的系统中没有安装IGMP软件包,你需要通过包管理器来安装它。

包管理器的使用方法因不同发行版而异。

例如,在Debian / Ubuntu上,你可以使用以下命令安装IGMP软件包:sudo apt-get install igmp-utils第三步:启用IGMP协议在Linux系统中,默认情况下IGMP是启用的。

你可以通过检查系统的配置文件来确认。

在大多数Linux系统中,IGMP的配置文件是`/etc/sysctl.conf`。

你可以使用以下命令来检查配置文件中IGMP的值:cat /etc/sysctl.conf grep igmp如果输出中包含以下行,则表示IGMP已启用:net.ipv4.igmp_max_memberships = 20第四步:使用IGMP工具Linux系统提供了一些IGMP相关的工具,用于管理和监控多播组。

下面是一些常用的IGMP工具:1. `ip maddr`:用于显示和配置多播组的工具。

它可以查看当前系统加入的多播组,也可以添加或删除多播组。

例如,你可以使用以下命令查看当前系统加入的多播组:ip maddr show2. `tcpdump`:用于抓取和分析网络数据包的工具。

数据链路层技术中的广播与多播实现机制(八)

数据链路层技术中的广播与多播实现机制(八)

数据链路层技术中的广播与多播实现机制1. 引言数据链路层是计算机网络中的关键层,负责在物理介质上传输数据帧。

在数据链路层中,广播和多播是两种重要的实现机制,它们在网络通信中扮演着不可或缺的角色。

本文将重点探讨数据链路层技术中的广播与多播实现机制。

2. 广播实现机制广播是一种向网络中的所有主机发送数据的机制。

在数据链路层中,广播通过以太网的广播地址(Broadcast Address)实现。

以太网的广播地址是一个特殊的MAC地址,表示广播帧应发送给所有连接到以太网上的设备。

在广播实现机制中,当源主机要发送广播帧时,它将目标MAC 地址设置为广播地址(FF-FF-FF-FF-FF-FF),并将数据发送给物理介质。

接收到广播帧的所有主机都会收到这个帧,并根据需要进行相应的处理。

广播实现机制的应用场景广泛,比如网络中的ARP(地址解析协议)是通过广播方式来获取目标主机的MAC地址。

3. 多播实现机制多播是一种向网络中的一组特定主机发送数据的机制。

在数据链路层中,多播通过以太网的多播地址(Multicast Address)实现。

以太网的多播地址是一个特殊的MAC地址,用于表示数据应发送给一组特定的设备。

多播实现机制中的发送方首先需要加入一个多播组,然后将目标MAC地址设置为多播地址,并将数据发送给物理介质。

加入多播组的接收方会收到发送方发出的多播帧,并根据需要进行相应的处理。

多播实现机制的应用场景丰富多样。

例如,在视频会议中,多个参与者可以加入同一个多播组,接收发送方发送的视频数据。

4. 广播与多播的区别与优势广播和多播实现机制在一定程度上相似,但也存在一些区别与优势。

首先,广播发送的数据帧会被网络中的所有主机接收,而多播发送的数据帧则只会被特定的主机组接收。

其次,广播通常用于向整个网络中的设备发送重要信息,而多播则可以用于向特定的设备组发送数据。

此外,由于多播发送的数据只有目标组中的设备接收,因此可以节省网络资源。

recvmsg sendmsg 使用方法

recvmsg sendmsg 使用方法

recvmsg sendmsg 使用方法recvmsg和sendmsg是在Linux系统中用于进行网络通信的两个系统调用。

它们可以实现在网络上接收和发送消息的功能。

本文将详细介绍recvmsg和sendmsg的使用方法,包括参数的设置、返回值的处理以及常见的应用场景。

一、recvmsg的使用方法recvmsg函数用于接收网络上的消息。

它的函数原型如下:```cssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);```其中,sockfd是指向已连接套接字的文件描述符;msg是指向msghdr结构的指针,该结构包含了接收消息所需的信息;flags是用于控制接收操作的标志位。

在使用recvmsg函数之前,需要先初始化msghdr结构。

msghdr 结构定义如下:```cstruct msghdr {void *msg_name; // 指向目标地址的指针socklen_t msg_namelen; // 目标地址的长度struct iovec *msg_iov; // 指向数据缓冲区的指针int msg_iovlen; // 数据缓冲区的长度void *msg_control; // 指向辅助数据的指针socklen_t msg_controllen;// 辅助数据的长度int msg_flags; // 接收操作的标志位};```在接收消息之前,需要设置msg_iov和msg_iovlen字段,分别指向数据缓冲区的指针和长度。

数据缓冲区用于存储接收到的消息内容。

接收消息的过程如下:1. 调用recvmsg函数,将接收到的消息存储在msg_iov指向的数据缓冲区中;2. 根据返回值判断接收是否成功,返回值大于0表示接收到的字节数,等于0表示对方已关闭连接,小于0表示接收错误。

二、sendmsg的使用方法sendmsg函数用于发送消息到网络。

linux网络编程--广播与组播

linux网络编程--广播与组播

linux⽹络编程--⼴播与组播⼴播 前⾯介绍的数据包发送⽅式只有⼀个接收⽅,称为单播 如果发送给局域⽹中的所有主机,称为⼴播 只有⽤户数据报(使⽤UDP协议)套接字才能⼴播⼴播地址: 以192.168.1.0(255.255.255.0)⽹段为例,最⼤的主机地址192.168.1.255代表该⽹段的⼴播地址 发送该地址的数据包被所有主机接收 255.255.255.255在所有⽹段中都代表⼴播地址⼴播发送 创建⽤户数据报套接字 缺省创建的套接字不允许⼴播数据包,需要设置属性--setsockopt可以设置套接字属性 接收⽅指定为⼴播地址 指定端⼝信息 发送数据包设置的选项: #include <> #include <sys/socket.h>int setsockopt(int sockfd, int level, int optname,const void *optval, socklen_t optlen); sockfd:标识⼀个套接⼝的描述字。

level:选项定义的层次;⽀持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。

optname:需设置的选项。

optval:,指向存放选项待设置的新值的。

optlen:optval缓冲区长度。

成功返回0,失败返回-1并设置errno⼴播发送代码:sockfd=socket()......int on=1setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));.........sendto(....);⼴播接收:创建⽤户数据报套接字绑定ip地址(⼴播ip或0.0.0.0)和端⼝ 绑定的端⼝必须和发送⽅的指定的端⼝相同等待接收数据实例如下:send.c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define err_log(errlog) do{perror(errlog); exit(1);}while(0)#define N 128// ./send 192.168.0.255 10000int main(int argc, const char *argv[]){int sockfd;struct sockaddr_in broadcastaddr;struct sockaddr_in clientaddr;socklen_t addrlen = sizeof(clientaddr);char buf[N] = {};if(argc < 3){fprintf(stderr, "usage:%s serverip port.\n", argv[0]);return -1;}if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){err_log("fail to socket");}broadcastaddr.sin_family = AF_INET;broadcastaddr.sin_addr.s_addr = inet_addr(argv[1]);broadcastaddr.sin_port = htons(atoi(argv[2]));int on = 1;if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {err_log("fail to setsockopt");}while(1){printf("Input > ");fgets(buf, N, stdin);buf[strlen(buf)-1] = '\0';if(sendto(sockfd, buf, N, 0, (struct sockaddr *)&broadcastaddr, addrlen) < 0) {err_log("fail to sendto");}if(strncmp(buf, "quit", 4) == 0){break;}printf("%s\n", buf);}close(sockfd);return0;}recv.c#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#define err_log(errlog) do{perror(errlog); exit(1);}while(0)#define N 128int main(int argc, const char *argv[]){int sockfd;struct sockaddr_in broadcastaddr;struct sockaddr_in clientaddr;socklen_t addrlen = sizeof(clientaddr);char buf[N] = {};if(argc < 3){fprintf(stderr, "usage:%s serverip port.\n", argv[0]);return -1;}if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){err_log("fail to socket");}broadcastaddr.sin_family = AF_INET;broadcastaddr.sin_addr.s_addr = inet_addr(argv[1]);broadcastaddr.sin_port = htons(atoi(argv[2]));if(bind(sockfd, (struct sockaddr*)&broadcastaddr, sizeof(broadcastaddr)) < 0){err_log("fail to bind");}while(1){if(recvfrom(sockfd, buf, N, 0, (struct sockaddr*)&clientaddr, &addrlen) < 0){err_log("fail to recvfrom");}printf("From clientaddr:%s\n", buf);strcat(buf, " from server...");}close(sockfd);return0;}编译运⾏测试 ./send 192.168.1.255 10000分别在两台局域⽹内的机器上测试./recv 192.168.1.255 10000 收到./recv 192.168.1.255 10000 收到(2)组播(多播) 单播⽅式只能发送给⼀个接收⽅ ⼴播⽅式发给所有的主机。

Linuxsocket编程探讨二(使用不同收发端口发送UDP广播)

Linuxsocket编程探讨二(使用不同收发端口发送UDP广播)

Linux socket编程探讨二(使用不同收发端口发送UDP广播)本文通过比较单播、多播、广播方式传送消息的不同,介绍了广播地址、任意端口等概念,进而通过实例介绍一种了使用不同收发端口发送UDP广播的方法,即发送端使用系统动态分配的端口,接收端使用指定端口,使用这种方法可以让在同一主机或者同一进程的收发端的请求和响应互不干扰。

1.引言在网络编程中,有时遇到这样的情形:需要向整个网络(或者局域网)内的主机发送询问消息并等待回应,如果挨个询问每个主机的话效率太低,我们常采用“广播”的方式发送消息和接收回应。

和TCP相比,UDP是无连接的、不可靠的数据包协议,但是如上提到的“广播消息”,由于TCP是有连接的而必须用到UDP。

实际上发送广播时时常遇到如此情形:发送广播的服务端同时也是客户端,也就是说既需要发送广播接收回应,又需要等待接收其他客户端的请求并返回回应。

如何区分接收到的回应和请求?本文提供了一种解决方案。

2. 步骤与实例2.1基本概念Socket网络编程中消息的传送方式分为3种:单播:信息的接收和传递只在两个节点之间进行,相当于“一对一”;多播:消息在发送者和加入了多播组的多个主机之间进行,相当于“一对多”;广播:消息在发送者和广播地址包含的所有主机进行,相当于“一对所有”。

TCP socket相当于单播;广播和多播仅应用于UDP socket,它们对需将报文同时传往多个接收者的应用来说十分重要。

广播消息的目的IP地址是一种特殊IP地址,称为广播地址。

广播地址由IP地址网络前缀加上全1主机后缀组成,如:192.168.1.255是192.169.1.0这个网络的广播地址;10.16.18.255是10.16.18.0这个网络的广播地址。

向全部为1的IP地址(255.255.255.255)发送消息的话,那么理论上全世界所有的联网的计算机都能收得到了。

但实际上不是这样的,一般路由器上设置抛弃这样的包,只在本地网内广播,所以效果和向本地网的广播地址发送消息是一样的。

Linux下广播与多播编程

Linux下广播与多播编程
Linux网络编程
第十单元 广播与多播编程
1/20
• 单播
– 一台主机向另一台主机发送数据
• 广播
– 一台主机向本子网内所有主机发送数据
• 多播
– 一台主机向网络中的部分主机发送数据
2/20
第十单元 广播与多播编程
• 10.1 广播的概念 • 10.2 多播的概念
3/20
3
主机A向B发送数据过程
– – – – 224.0.0.0 保留 224.0.0.1 本子网上所有主机 224.0.0.2 本子网上所有网关 224.0.1.1 NTP(网络时间协议)组
12/20
多播的原理
• 当一个多播分组到达一个以太网时,形成帧后它 的MAC地址为01:00:5e:xx:xx:xx,其后23位由多播 组标识的后23位映射而成。 • 例如目的地址为224.0.1.1的多播分组,在以太网 上帧的MAC地址就为01:00:5e:00:01:01。
10/20
多播
• 多播是对单播和广播的一种折中方案。 • 广播限于局域网,多播可以用于局域网也 可跨广域网。
11/20
多播地址
• 多播是通过D类地址进行的,D类地址的前4 位为1110,后面28位为多播的组标识。 • 地址范围224.0.0.0 到239.255.255.255 • 特殊的IPv4多播地址:
17/20
多播的举例
• 服务器端程序没有什么改变,只要将设置 socket选项SO_BROADCAST的那行去掉就 可以了。 • 客户程序源码P157。
18/20
第十单元 小结
• • • • • 单播、广播、多播区别。 广播地址 广播的实现过程 多播地址 多播的实现过程
19/20

linux vxlan group 多播 原理

linux vxlan group 多播 原理

linux vxlan group 多播原理
Linux VXLAN组播的原理是通过多播组地址来实现多个VTEP(VXLAN Tunnel Endpoint)之间的通信。

具体原理如下:
1. 在VXLAN网络中,VTEP负责将数据报封装入VXLAN封装协议中,并添加VXLAN头部信息。

2. 当一个VTEP收到一个VXLAN封装的数据包时,它会解析VXLAN头部信息,提取出原始数据包,并根据VNI (VXLAN Network Identifier)确定目标VTEP。

3. VTEP使用IGMP(Internet Group Management Protocol)或者MLD(Multicast Listener Discovery)协议来加入一个多播组。

通过配置IGMP或MLD协议,VTEP可以将自己加入到指定的多播组,并且能够通过网络上的路由器接收到相应的多播组数据。

4. 当一个VTEP需要发送数据时,它会封装数据报为VXLAN 封装协议,并使用目标VTEP的IP地址进行发送。

5. 网络上的路由器会根据VXLAN数据报的目标VTEP的IP 地址,将数据报转发到相应的VTEP上。

6. 目标VTEP收到VXLAN数据报后,根据VXLAN头部信息中的VNI确定目标虚拟网络,并将原始数据包解封,然后交付给相应的虚拟机或系统进程。

通过使用多播协议,VXLAN组播可以实现VXLAN网络中的广播和组播通信。

这样,只需要在需要通信的VTEP上配置多
播地址,并加入相应的多播组,就能够实现VTEP之间的组播通信。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.概念单播是用于两个主机之间传送数据,广播是一个主机对局域网内的所有主机发送数据。

而多播,又称为组播,它是对一组特定的主机通信。

将网络上同一类型业务逻辑上分组,只和组内的成员通信,其它主机没有加入组则不能通信。

与单播相同的是,组播允许在Internet上通信,而广播只是同一局域网内的主机通信。

组播地址是特定的,D类地址用于组播,即244.0.0.0到239.255.255.255. 并划分为局部连接多播地址,预留多播地址和管理权限多播地址3类。

(1)局部多播地址(224.0.0.-224.0.0.255)为路由协议和其它用途保留的地址,路由器不转发此范围的IP包(2)预留多播地址(224.0.1.0-238.255.255.255)可用于全球范围内或网络协议(3)管理权限的多播(239.0.0.0-239.255.255.255) 可供组织内使用,类型于私有IP,不用于Internet,可限制多播范围2. 多播套接字设置可用setsockopt或getsockopt设置或得到多播选项. 常用的多播选项如下所示:IP_MULTICAST_TTL 设置多播的TTL值IP_MULTICAST_IF 获取或设置多播接口IP_MULTICAST_LOOP 禁止多播数据回送到本地loop接口IP_ADD_MEMBERSHIP 将指定的接口加入多播IP_DROP_MEMBERSHIP 退出多播组struct ip_mreq{struct in_addr imn_multicastaddr;//多播组地址struct in_addr imr_interface;//加入的接口的IP地址}int ttl=255;setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl));//设置跳数s-套接字描述符PROTO_IP-选项所在的协议层IP_MULTICAST_TTL-选项名&ttl-设置的内存缓冲区sizeof(ttl)-设置的内存缓冲区长度struct in_addr in;setsockopt(s,IPPROTO_IP,IP_MUTLICAST_IF,&in,sizeof(in));//设置组播接口int yes=1;setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,&yes,sizeof(yes));//设置数据回送到本地回环接口struct ip_mreq addreq;setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&req,sizeof(req));//加入组播组struct ip_mreq dropreq;setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,&dropreq,sizeof(dropreq));//离开组播组3. 多播程序的设计流程(1)建立socket(2)设置TTL值IP_MULTICAST_TTL(3)设置是否允许本地回环IP_MULTICAST_LOOP(4)加入多播组IP_ADD_MEMBERSHIP(5)发送数据send(6)接收数据recv(7)退出多播组IP_DROP_MEMBERSHIP注意: TCP协议也不能用于多播.4. 多播实例服务器端不停的向加入多播组的主机发送数据.服务器:#include <sys/socket.h>#include <sys/types.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <arpa/inet.h>/**广播与多播只支持UDP协议,因为TCP协议是端到端,这与广播与多播的理念相冲突广播是局域网中一个主机对所有主机的数据通信,而多播是一个主机对一组特定的主机进行通信.多播可以是因特网,而广播只能是局域网。

多播常用于视频电话,网上会议等。

setsockopt设置套接字选项可以设置多播的一些相关信息IP_MULTICAST_TTL //设置多播的跳数值IP_ADD_MEMBERSHIP //将主机的指定接口加入多播组,以后就从这个指定的接口发送与接收数据IP_DROP_MEMBERSHIP //主机退出多播组IP_MULTICAST_IF //获取默认的接口或设置多播接口IP_MULTICAST_LOOP //设置或禁止多播数据回送,即多播的数据是否回送到本地回环接口struct ip_mreq{struct in_addr imn_multicastaddr;//多播组地址struct in_addr imr_interface;//加入的接口的IP地址}例子:int ttl=255;setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl));//设置跳数s-套接字描述符PROTO_IP-选项所在的协议层IP_MULTICAST_TTL-选项名&ttl-设置的内存缓冲区sizeof(ttl)-设置的内存缓冲区长度struct in_addr in;setsockopt(s,IPPROTO_IP,IP_MUTLICAST_IF,&in,sizeof(in));//设置组播接口int yes=1;setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,&yes,sizeof(yes));//设置数据回送到本地回环接口struct ip_mreq addreq;setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&req,sizeof(req));//加入组播组struct ip_mreq dropreq;setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,&dropreq,sizeof(dropreq));//离开组播组组播程序的设计流程:(1)建立socket(2)设置跳数TTL(3)设置是否允许本地回环(4)加入组播组(5)发送数据(6)接收数据(7)离开多播组(8)关闭套接字**///服务器实现向多播组发送数据#define MCAST_PORT 8888#define MCAST_ADDR "224.0.0.88"int main(int argc,char*argv[]){int ret;int s;int i=1;struct sockaddr_in Multi_addr;//多播地址struct sockaddr_in client_addr;s=socket(AF_INET,SOCK_DGRAM,0);//建立数据报套接字if(s<0){perror("socket error");return -1;}Multi_addr.sin_family=AF_INET;Multi_addr.sin_port=htons(MCAST_PORT);//多播端口Multi_addr.sin_addr.s_addr=inet_addr(MCAST_ADDR);//多播地址//向多播组发送数据char buffer[1024];for(;;){memset(buffer,0,sizeof(buffer));sprintf(buffer,"%d",i);int size=sendto(s,buffer,strlen(buffer),0,(struct sockaddr*)&Multi_addr,sizeof(Multi_addr)); if(size<0){perror("sendto error");}sleep(1);i++;memset(buffer,0,sizeof(buffer));int len=sizeof(client_addr);size=recvfrom(s,buffer,1024,0,(struct sockaddr*)&client_addr,&len);write(1,buffer,size);}close(s);}加入多播组的主机:#include <sys/types.h>#include <sys/socket.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <netinet/in.h>//多播的客户端程序#define PORT 8888#define MCAST "224.0.0.88"int main(int argc,char*argv[]){int s;int ret;int size;int ttl=10;//如果转发的次数等于10,则不再转发int loop=0;int times=0;char buffer[1024];struct sockaddr_in localaddr,fromaddr;//多播地址结构//建立套接字s=socket(AF_INET,SOCK_DGRAM,0);if(s<0){perror("socket error");return -1;}//多播的地址结构localaddr.sin_family=AF_INET;localaddr.sin_port=htons(PORT);//多播端口号localaddr.sin_addr.s_addr=htonl(INADDR_ANY);//接收任意地址发送的数据//绑定地址结构到套接字ret=bind(s,(struct sockaddr*)&localaddr,sizeof(localaddr));//客户端需要绑定端口,用来接收服务器的数据,得指定接收端口,因为数据先从服务器发送过来的if(ret<0){perror("bind error");return -1;}//设置多播的TTL值if(setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,&ttl,sizeof(ttl))<0){perror("IP_MULTICAST_TTL");return -1;}//设置数据是否发送到本地回环接口if(setsockopt(s,IPPROTO_IP,IP_MULTICAST_LOOP,&loop,sizeof(loop))<0){perror("IP_MULTICAST_LOOP");return -1;}//客户端加入多播组struct ip_mreq mreq;mreq.imr_multiaddr.s_addr=inet_addr(MCAST);//多播组的IPmreq.imr_interface.s_addr=htonl(INADDR_ANY);//本机的默认接口IPif(setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq))<0){perror("IP_ADD_MEMBERSHIP");return -1;}//循环接收多播组的消息,5次退出for(times=0;times<20;times++){int len=sizeof(fromaddr);memset(buffer,0,sizeof(buffer));size=recvfrom(s,buffer,1024,0,(struct sockaddr*)&fromaddr,&len);if(size<0){perror("recvfrom ");return -1;}printf("receive message:%s\n",buffer);printf("Port is:%d\n",fromaddr.sin_port);size=sendto(s,"OK",2,0,(struct sockaddr*)&fromaddr,sizeof(fromaddr));//向服务器发送数据,向服务器指定的IP与端口发送数据}//离开多播组ret=setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,&mreq,sizeof(mreq));if(ret<0){perror("IP_DROP_MEMBERSHIP");return -1;}close(s);return 0;}说明:设置主机的TTL值,是否允许本地回环,加入多播组,然后服务器向加入多播组的主机发送数据,主机接收数据,并响应服务器。

相关文档
最新文档