【TCP/IP】多播 - 定义、原理及编程实现(TTL、多播组、收发信息)

这篇具有很好参考价值的文章主要介绍了【TCP/IP】多播 - 定义、原理及编程实现(TTL、多播组、收发信息)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

多播

多播的原理

多播的数据传输时的特点

TTL 的概念

TTL 和 多播组的配置方法

多播的编程与实现

发送者

接收者


多播

        多播是一种介于单播和广播通信之间的技术方式,可以将发送者所需要发送的数据包分别发送给分散在不同子网中的一组接收者。

多播的原理

        多播的基础概念是“组”。一个多播组(multicast group)就是一组希望接收特定数据流的接收者,这个组没有物理或者地理的边界:组内的主机可位于互联网或者专用网络的任何地方。

        多播组中的每个节点被称为多播组成员(multicastgroupmember)。多播的数据传输协议基于UDP完成。采用多播方式时,可以同时向多个主机传递数据。

多播的数据传输时的特点

  • 多播服务器端针对特定多播组,只发送 1 次数据。
  • 即使只发送 1 次数据,但该组内的所有客户端都会接收数据。
  • 多播组数可在IP地址范围内任意增加。
  • 加入特定组即可接收发往该多播组的数据。 

        多播组的地址属于D类,即 224.0.0.0 ~ 239.255.255.255在发送多播数据包时(路由器得支持这项功能),需要有机器加入到多播组中以接收发来的数据包,同时路由器担负起将该数据包复制并传递到多个主机中的任务。如下图所示:

【TCP/IP】多播 - 定义、原理及编程实现(TTL、多播组、收发信息)

TTL 的概念

        传输多播数据包时,需要给程序设置TTL(TIme to Live 生存时间),这是决定数据包能否及时准确到达目标点的关键参数。

        TTL用整数表示,每经过1个路由器该数值便会减1。当TTL变为0时,该数据包将无法再被传递,作销毁处理。因此,在TTL的值上需要合理设置,过大会影响网络流量,过小将无法将数据包及时传递到目标。

【TCP/IP】多播 - 定义、原理及编程实现(TTL、多播组、收发信息)

TTL 和 多播组的配置方法

        在编程中,我们可以实现对 TTL 的设置。TTL相关的协议层为IPPROTO_IP,选项名为IP_MULTICAST_TTL,通过使用setsocketopt这个函数进行设置。

        代码如下:

int sock;
int ttl = 64;

sock = socket(PF_INET, SOCK_DGRAM, 0);
setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&ttl, sizeof(ttl));

        同样,加入到多播组也是通过 setsocketopt 函数完成。多播组加入的协议层为IPPROTO_IP,选项名为IP_ADD_MEMBERSHIP。 

        代码如下:

int recv_sock;
struct ip_mreq groupjoin_adr;

recv_sock = socket(PF_INET, SOCK_DGRAM, 0);

join_adr.imr_multiaddr.s_addr = "多播组的地址";
join_adr.imr_interace.s_addr = "加入多播组的主机地址";
setsockopt(recv_sock , IPPROTO_IP , IP_ADD_MEMBERSHIP , (void*) & groupjoin_adr), sizeof(groupjoin_adr));

        其中 ip_mreq 结构体,定义如下:

struct ip_mreq
  {
    /* 欲加入的多播组的地址.  */
    struct in_addr imr_multiaddr;

    /* 所属主机的IP地址. 可以使用INADDR_ANY  */
    struct in_addr imr_interface;
  };

多播的编程与实现

        多播中区分 发送者(Sender)接收者(Receiver)。发送者指的是发送多播数据的主体,接收者指的是位于多播组中的欲接收多播数据的主体。

发送者

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

#define TTL 64
#define BUF_SIZE 1024

void Sender_message(char *message)
{
	puts(message);
	exit(1);
}

int main(int argc, char *argv[])
{
	int send_sock;
	struct sockaddr_in mul_addr;
	int time2live = TTL;
	FILE *fp;
	char buf[BUF_SIZE];

	send_sock = socket(PF_INET, SOCK_DGRAM, 0);
	memset(&mul_addr, 0, sizeof(mul_addr));

	mul_addr.sin_family = AF_INET;
	mul_addr.sin_addr.s_addr = inet_addr(argv[1]); // 多播地址
	mul_addr.sin_port = htons(atoi(argv[2]));	   // 多播端口号

	setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time2live, sizeof(time2live));

	fp = fopen(argv[3], "r");
	if (fp == NULL)
	{
		Sender_message((char*)"file open error");
	}

	while (!feof(fp)) /* 发送数据 */
	{
		fgets(buf, BUF_SIZE, fp);
		sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr *)&mul_addr, sizeof(mul_addr));
	}

	fclose(fp);
	close(send_sock);
	return 0;
}

接收者

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

#define BUF_SIZE 1024

//报错消息发送
void Sender_message(char *message)
{
    puts(message);
    exit(1);
}

int main(int argc, char *argv[])
{
    int recv_sock;
    int str_len;
    char buf[BUF_SIZE];
    struct sockaddr_in addr;
    struct ip_mreq join_addr;

    recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
    memset(&addr, 0, sizeof(addr));

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(atoi(argv[2]));

    if (bind(recv_sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
    {
        Sender_message((char*)"bind error");
    }

    join_addr.imr_multiaddr.s_addr = inet_addr(argv[1]);
    join_addr.imr_interface.s_addr = htonl(INADDR_ANY);

    setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&join_addr, sizeof(join_addr));

    while (1)
    {
        // 接收多播数据 其中第五、第六个参数在不知道主机地址时可设为NULL和0
        str_len = recvfrom(recv_sock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (str_len < 0)
        {
            break;
        }
        buf[str_len] = 0;
        fputs(buf, stdout);
    }

    close(recv_sock);
    return 0;
}

运行结果

【TCP/IP】多播 - 定义、原理及编程实现(TTL、多播组、收发信息)文章来源地址https://www.toymoban.com/news/detail-499534.html

到了这里,关于【TCP/IP】多播 - 定义、原理及编程实现(TTL、多播组、收发信息)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux C | 网络编程】多播的概念、多播地址、UDP实现多播的C语言例子

    😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭 🤣本文内容🤣:🍭介绍多播的概念、多播地址、UDP实现广播的C语言例子 🍭 😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭

    2024年03月11日
    浏览(54)
  • 网卡收发包系统结构收发包流程,tcp/ip协议,socket套接字缓冲区,滑动窗口,mtu/mss

    MTU和MSS的区别 TCP 的 MTU MSS MTU是在数据链路层的载荷大小也就是传给网络层的大小,mss是在传输层的载荷大小也就是传给应用层的大小 mss是根据mtu得到的 1、MTU: Maximum Transmit Unit,最大传输单元,即物理接口(数据链路层)提供给其上层(通常是IP层)最大一次传输数据的大

    2024年02月08日
    浏览(43)
  • 《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输

    主要需求:         服务器端和客户端各传递 1 次字符串,基于 TCP 协议,传递字符串前先以 4 字节整数型方式传递字符串长度,剩余部分为字符串数据; 注:下面的代码基于 Windows 系统实现; 项目链接:Chapter5

    2024年02月09日
    浏览(55)
  • 互联网编程之基于 TCP 的单线程文件收发程序(CS架构)

    目录 需求 服务端实现 客户端实现 测试 可试着根据java编程课所学到的java socket编程技术,尝试编写一个基于 TCP 的单线程文件收发程序,需满足: 服务端程序预先定义好需要发送的文件并等待客户端的连接。 客户端连接成功后,服务端将文件发送给客户端,客户端将文件保

    2024年02月12日
    浏览(67)
  • TCP/IP网络编程(1)——基于TCP的服务端和客户端的简单实现

    目录 前言 一、服务器端函数 1. 创建套接字函数 socket 2. 套接字绑定地址函数 bind 3. 等待连接请求函数 listen 4. 处理连接请求函数 accept 5. 关闭套接字函数 close 二、客户端函数 1. 请求连接函数 connect 三、完整代码 四、 基于TCP的半关闭 shutdown 五、 套接字可选项 getsockopt setsoc

    2024年02月07日
    浏览(58)
  • Linux网络编程——C++实现进程间TCP/IP通信

    地址接口 1、通用地址接口 共16字节 = 2字节地址类型 + 14字节地址数据 2、自定义地址接口 地址转换 1、需要将点分字符串ip转化为程序ip,使用inet_addr函数: 2、字节序转换 地址接口配置中的端口需要字节序转换,网络规定使用大端字节序。 地址接口配置 1、socket:创建套接

    2024年02月20日
    浏览(57)
  • 【JavaEE】从收发消息的角度理解 TCP/IP 五层网络模型的封装与分用

    你问我为啥需要分层?那必然是有好处的啊! 我们来回顾一下面向接口编程有什么特点~ 对于使用方来说,不必关心提供方是如何实现的, 只需要使用接口即可; 对于提供方来说,只需要利用封装的特性,隐藏内部实现细节,对外开发接口。 而对于协议的分层也是类似,后

    2024年02月03日
    浏览(33)
  • 【C语言实现windows环境下Socket编程TCP/IP协议】

    代码是别人的,问题是我的。顺便记录一下遇见的各种问题和我的解决办法。 可能的解决方案: 1、服务端和客户端不在一个局域网,可以开热点,这样就在了。然后ipconfig查看IP地址,就ok了。至于怎么查看在不在就ping一下对方就好了。 2、一个局域网下也ping不通:看看自己

    2024年02月04日
    浏览(48)
  • Socket网络编程(TCP/IP)实现服务器/客户端通信。

    一.前言 回顾之前进程间通信(无名管道,有名管道,消息队列,共享内存,信号,信号量),都是在同一主机由内核来完成的通信。 那不同主机间该怎么通信呢? 可以使用Socket编程来实现。 Socket编程可以通过网络来实现实现不同主机之间的通讯。 二.Socket编程的网络模型如

    2024年02月08日
    浏览(89)
  • Linux内核--网络协议栈(五)TCP IP栈的实现原理与具体过程

    一、引言 二、Linux内核的结构 三、Linux网络子系统 四、TCP/IP协议栈 ------4.1、网络架构 ------4.2、协议无关接口 ------4.3、套接口缓存 ------4.4、重要的数据结构 五、网络信息处理流程 ------5.1、硬中断处理 ------5.2、ksoftirqd内核线程处理软中断 ------5.3、网络协议栈处理 ------5.4、

    2024年01月21日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包