《TCP/IP网络编程》学习笔记 | Chapter 14:多播与广播

《网络编程》广播和多播 在网络协议中 IP 地址有三种方式,即为单播地址、广播地址 以及 多播地址。假设多个主机上的共享信道网络是以太网,每个以太网帧包含源主机和目的主机的以太网地址。若目的地址仅指定单个接收接口,则称为单播,在单播方式下,任意两台主机之间的通信不会干扰网内其他主机。若目的地址包含网上的所有主机的接收接口时,即一个主机要向网上所有主机发送帧,则称为广播。若一个主机把帧发送给属于多播组的多个主机,则称为多播。广播和多播仅应用于 UDP,可以将数据报文同时传给多个接收者,而 TCP 是一个面向连接的字节流协议,意味着只 阅读详情

《TCP/IP网络编程》学习笔记 | Chapter 14:多播与广播

多播

多播(Multicast)方式的数据传输是基于UDP完成的,可以同时向多个主机传递数据。

多播常用于视频会议、在线直播、IPTV等场景,其中数据需要发送给多个特定的接收者而不是所有人。

多播的数据传输方式和特点

多播的特点:

  1. 多播服务器针对特定的多播组,只发送一次数据。
  2. 即使只发送一次数据,该组内所有客户端都会接受到数据。
  3. 多播组数可以在IP地址范围内任意增加。
  4. 加入多播组就能收到发往该多播组的数据。

多播组时D类IP地址,即224.0.0.0~239.255.255.255,并被划分为三类:

  • 局部链接多播地址:224.0.0.0~224.0.0.255,这是为路由协议和其它用途保留的地址,路由器并不转发属于此范围的IP包。
  • 预留多播地址:224.0.1.0~238.255.255.255,可用于全球范围(如Internet)或网络协议。
  • 管理权限多播地址:239.0.0.0~239.255.255.255,可供组织内部使用,类似于私有IP地址,不能用于Internet,可限制多播范围。

「加入多播组」可以理解为通过程序完成如下声明:在 D 类IP地址中,我希望接收发往目标 239.234.218.234 的多播数据。

多播技术基于UDP传输,向网络传输1个多播数据包时,路由器会复制该数据包并传递到多个主机,如下图所示:

在这里插入图片描述

多播的传输需要借助路由器完成。若通过 TCP 或 UDP 向 1000 个主机发送文件,则共需要传递 1000 次。但是此时如果用多播网络传输文件,则只需要发送一次。正是由于这样的特性,大大节省了网络流量,减少了占用带宽,同时也减少了发送端的重复无用的工作,多播主要用于“多媒体数据的实时传输”。

要实现多播通信,要求介于多播源和接收者之间的路由器、集线器、交换机以及主机均需支持IP多播。目前,IP多播技术已得到硬件、软件厂商的广泛支持。

然而,有些路由器并不支持多播,或即便支持也因网络拥堵问题故意阻断多播。因此,为了在不支持多播的路由器中完成多播通信,也会使用隧道(Tunneling)技术。

路由(Routing)和 TTL(Time to Live,生存时间),以及加入组的办法

为了传递多播数据包,必须设置 TTL ,它是决定「数据包传递距离」的主要因素。TTL 用整数表示,并且每经过一个路由器就减一。TTL 变为 0 时,该数据包就无法再被传递,只能销毁。因此,TTL 的值设置过大将影响网络流量。当然,设置过小,也无法传递到目标。

在这里插入图片描述

缺省情况下,发送 IP 多播数据报时其 TTL 值为 1。与设置 TTL 相关的协议层为 IPPROTO_IP ,选项名为 IP_MULTICAST_TTL。这些阈值将针对具有以下初始 TTL 值的多播数据报强制实施相应约定:

  • 0:限定在同一主机
  • 1:限定在同一子网
  • 32:限定在同一站点
  • 64:限定在同一地区
  • 128:限定在同一洲
  • 255:范围不受限制

站点和地区并未严格定义,站点可以根据实际情况再分为更小的管理单元。

因此,可以用如下代码把 TTL 设置为 64:

int send_sock;
int time_live = 64;
...
send_sock = socket(PF_INET, SOCK_DGRAM, 0);
setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time_live, sizeof(time_live));
...

加入多播组也通过设置套接字可选项来完成。加入多播组相关的协议层为 IPPROTO_IP,选项名为 IP_ADD_MEMBERSHIP 。可通过如下代码加入多播组:

int recv_sock;
struct ip_mreq join_adr;
...
recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
...
join_adr.imr_multiaddr.s_addr = "多播组地址信息";
join_adr.imr_interface.s_addr = "加入多播组的主机地址信息";
setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&join_adr, sizeof(join_adr));
...

下面是 ip_mreq 结构体的定义:

struct ip_mreq
{
    struct in_addr imr_multiaddr; // 写入加入组的IP地址
    struct in_addr imr_interface; // 加入该组的套接字所属主机的IP地址
};

有关多播的实现需要设置UDP套接字的一些可选项,以表格的形式进行汇总:

IPPROTO_IP 选项名说明数据类型
IP_MULTICAST_TTL生存时间(Time To Live),组播传送距离int
IP_ADD_MEMBERSHIP加入组播struct ip_mreq
IP_DROP_MEMBERSHIP离开组播struct ip_mreq
IP_MULTICAST_IF获取默认接口或设置接口int
IP_MULTICAST_LOOP组播数据回送,缺省默认回送int

实现多播 Sender 和 Receiver

多播中用「发送者」(以下称为 Sender) 和「接收者」(以下称为 Receiver)替代服务器端和客户端。顾名思义,此处的 Sender 是多播数据的发送主体,Receiver 是需要多播组加入过程的数据接收主体。下面是示例,示例的运行场景如下:

  • Sender : 向 AAA 组广播(Broadcasting)文件中保存的新闻信息
  • Receiver : 接收传递到 AAA 组的新闻信息。

news_sender.c 程序:

#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 30

void error_handling(char *message);

int main(int argc, char *argv[])
{
    int send_sock;
    struct sockaddr_in mul_adr;
    int time_live = TTL;
    FILE *fp;
    char buf[BUF_SIZE];
    if (argc != 3)
    {
        printf("Usage : %s <GroupIP> <PORT>\n", argv[0]);
        exit(1);
    }
    send_sock = socket(PF_INET, SOCK_DGRAM, 0); // 创建  UDP 套接字
    memset(&mul_adr, 0, sizeof(mul_adr));
    mul_adr.sin_family = AF_INET;
    mul_adr.sin_addr.s_addr = inet_addr(argv[1]); // 必须将IP地址设置为多播地址
    mul_adr.sin_port = htons(atoi(argv[2]));
    // 指定套接字中 TTL 的信息
    setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&time_live, sizeof(time_live));
    if ((fp = fopen("news.txt", "r")) == NULL)
        error_handling("fopen() error");

    while (!feof(fp)) // 如果文件没结束就返回0
    {
        fgets(buf, BUF_SIZE, fp);
        sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr *)&mul_adr, sizeof(mul_adr));
        sleep(2);
    }
    fclose(fp);
    close(send_sock);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

news_receiver.c 程序:

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

#define BUF_SIZE 30

void error_handling(char *message);

int main(int argc, char *argv[])
{
    int recv_sock;
    int str_len;
    char buf[BUF_SIZE];
    struct sockaddr_in adr;
    struct ip_mreq join_adr;
    if (argc != 3)
    {
        printf("Usage : %s <GroupIP> <PORT>\n", argv[0]);
        exit(1);
    }
    recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
    memset(&adr, 0, sizeof(adr));
    adr.sin_family = AF_INET;
    adr.sin_addr.s_addr = htonl(INADDR_ANY);
    adr.sin_port = htons(atoi(argv[2]));

    if (bind(recv_sock, (struct sockaddr *)&adr, sizeof(adr)) == -1)
        error_handling("bind() error");
    // 初始化结构体
    join_adr.imr_multiaddr.s_addr = inet_addr(argv[1]); // 多播组地址
    join_adr.imr_interface.s_addr = htonl(INADDR_ANY);  // 待加入的IP地址
    // 利用套接字选项 IP_ADD_MEMBERSHIP 加入多播组,完成了接受指定的多播组数据的所有准备
    setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&join_adr, sizeof(join_adr));

    while (1)
    {
        // 通过 recvfrom 函数接受多播数据。如果不需要知道传输数据的主机地址信息,可以向recvfrom函数的第5 6参数分贝传入 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;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

通过结果可以看出,使用 sender 多播信息,通过 receiver 接收广播,如果延迟运行 receiver 将无法接受之前发送的信息。

广播

广播(Broadcast)在「一次性向多个主机发送数据」这一点上与多播类似,但传输数据的范围有区别。多播即使在跨越不同网络的情况下,只要加入多播组就能接受数据。相反,广播只能向同一网络中的主机传输数据。

广播的理解和实现方法

广播是向同一网络中的所有主机传输数据的方法。与多播相同,广播也是通过 UDP 来完成的。根据传输数据时使用的IP地址形式,广播分为以下两种:

  • 直接广播(Directed Broadcast):向特定区域内的所有主机传输数据。广播的IP地址除了网络地址外,其余主机地址全部设置为1,例如希望向 192.168.1.32 所在网络中的所有主机发送广播数据时可以向 192.168.1.255 传输。
  • 本地广播(Local Broadcast):本地广播的IP地址限定为 255.255.255.255,向该主机所在网络的所有主机发送广播数据。例如,192.32.24 网络中的主机向 255.255.255.255 传输数据时,数据将传输到 192.32.24 网络中所有主机。

有关广播的实现需要设置UDP套接字的一些可选项:

SOL_SOCKET 选项名说明数据类型
SO_BROADCAST允许或禁止发送广播数据(1启用,0不启用)int

数据通信中使用的IP地址是与 UDP 示例的唯一区别。默认生成的套接字会阻止广播,因此,只需通过如下代码更改默认设置:

int send_sock;
send_sock = socket(AF_INET, SOCK_DGRAM, 0); // 使用UDP传输

int opt = 1; // 启用广播
setsockopt(send_sock, SOL_SOCKET, SOL_SOCKET, (void *)&opt, sizeof(opt));

实现广播数据的 Sender 和 Receiver

news_sender_brd.c 程序:

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

#define BUF_SIZE 30
void error_handling(char *message);

int main(int argc, char *argv[])
{
    int send_sock;
    struct sockaddr_in broad_adr;
    FILE *fp;
    char buf[BUF_SIZE];
    int so_brd = 1;
    if (argc != 3)
    {
        printf("Usage : %s <GroupIP> <PORT>\n", argv[0]);
        exit(1);
    }
    send_sock = socket(PF_INET, SOCK_DGRAM, 0); // 创建  UDP 套接字
    memset(&broad_adr, 0, sizeof(broad_adr));
    broad_adr.sin_family = AF_INET;
    broad_adr.sin_addr.s_addr = inet_addr(argv[1]);
    broad_adr.sin_port = htons(atoi(argv[2]));
    setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (void *)&so_brd, sizeof(so_brd));
    if ((fp = fopen("news.txt", "r")) == NULL)
        error_handling("fopen() error");

    while (!feof(fp)) // 如果文件没结束就返回0
    {
        fgets(buf, BUF_SIZE, fp);
        sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr *)&broad_adr, sizeof(broad_adr));
        sleep(2);
    }
    fclose(fp);
    close(send_sock);
    return 0;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

news_receiver_brd.c 程序:

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

#define BUF_SIZE 30
void error_handling(char *message);

int main(int argc, char *argv[])
{
    int recv_sock;
    int str_len;
    char buf[BUF_SIZE];
    struct sockaddr_in adr;
    if (argc != 2)
    {
        printf("Usage : %s <PORT>\n", argv[0]);
        exit(1);
    }
    recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
    memset(&adr, 0, sizeof(adr));
    adr.sin_family = AF_INET;
    adr.sin_addr.s_addr = htonl(INADDR_ANY);
    adr.sin_port = htons(atoi(argv[1]));

    if (bind(recv_sock, (struct sockaddr *)&adr, sizeof(adr)) == -1)
        error_handling("bind() error");
    while (1)
    {
        // 通过 recvfrom 函数接受数据。如果不需要知道传输数据的主机地址信息,可以向recvfrom函数的第5 6参数分贝传入 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;
}

void error_handling(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

基于 Windows 的实现

在Windows平台中,该技术的套接字设置没有区别,只需要修改对应的变量和头文件即可。

基于 Windows 的多播示例程序

news_sender_win.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#define TTL 64
#define BUF_SIZE 30

void ErrorHanding(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    SOCKET sendSock;
    SOCKADDR_IN mulAddr;
    int timeLive = TTL;
    char buf[BUF_SIZE];

    if (argc != 3)
    {
        printf("Usage: %s <GroupIP> <port>\n", argv[0]);
        exit(1);
    }

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    sendSock = socket(PF_INET, SOCK_DGRAM, 0);
    if (sendSock == INVALID_SOCKET)
        ErrorHanding("socket() error!");

    memset(&mulAddr, 0, sizeof(mulAddr));
    mulAddr.sin_family = AF_INET;
    mulAddr.sin_addr.s_addr = inet_addr(argv[1]);
    mulAddr.sin_port = htons(atoi(argv[2]));

    setsockopt(sendSock, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&timeLive, sizeof(timeLive));

    FILE *fp = fopen("news.txt", "r");
    if (fp == NULL)
        ErrorHanding("fopen() error!");

    while (!feof(fp))
    {
        fgets(buf, BUF_SIZE, fp);
        sendto(sendSock, buf, strlen(buf), 0, (SOCKADDR *)&mulAddr, sizeof(mulAddr));
        Sleep(2000);
    }

    closesocket(sendSock);
    WSACleanup();

    return 0;
}

news_receiver_win.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#define BUF_SIZE 30

void ErrorHanding(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    SOCKET recvSock;
    SOCKADDR_IN recvAddr;
    struct ip_mreq joinAddr;
    int strLen;
    char buf[BUF_SIZE];

    if (argc != 3)
    {
        printf("Usage: %s <GroupIP> <port>\n", argv[0]);
        exit(1);
    }

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    recvSock = socket(PF_INET, SOCK_DGRAM, 0);
    if (recvSock == INVALID_SOCKET)
        ErrorHanding("socket() error!");

    memset(&recvAddr, 0, sizeof(recvAddr));
    recvAddr.sin_family = AF_INET;
    recvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    recvAddr.sin_port = htons(atoi(argv[2]));

    if (bind(recvSock, (SOCKADDR *)&recvAddr, sizeof(recvAddr)) == SOCKET_ERROR)
        ErrorHanding("bind() error!");

    joinAddr.imr_multiaddr.s_addr = inet_addr(argv[1]);
    joinAddr.imr_interface.s_addr = htonl(INADDR_ANY);
    if (setsockopt(recvSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&joinAddr, sizeof(joinAddr)) == SOCKET_ERROR)
        ErrorHanding("setsocket() error!");

    while (1)
    {
        strLen = recvfrom(recvSock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (strLen < 0)
            break;
        buf[strLen] = '\0';
        fputs(buf, stdout);
    }

    closesocket(recvSock);
    WSACleanup();

    return 0;
}

编译:

gcc news_sender_win.c -lwsock32 -o newsSendWin
gcc news_receiver_win.c -lwsock32 -o newsRecvWin

运行结果:

// 接收端
C:\Users\81228\Documents\Program\TCP IP Project\Chapter 14>newsRecvWin 224.1.1.2 9190
A powerful magnitude-7.7 earthquake struck central Myanmar on Friday, causing widespread devastation. The confirmed death toll from the earthquake has risen to 1,644.
// 发送端
C:\Users\81228\Documents\Program\TCP IP Project\Chapter 14>newsSendWin 224.1.1.2 9190

基于 Windows 的本地广播示例程序

news_sender_local_broad_win.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#define BUF_SIZE 30

void ErrorHanding(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    SOCKET sendSock;
    SOCKADDR_IN localBroadAddr;
    int brd = 1;
    char buf[BUF_SIZE];

    if (argc != 3)
    {
        printf("Usage: %s <GroupIP> <port>\n", argv[0]);
        exit(1);
    }

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    sendSock = socket(PF_INET, SOCK_DGRAM, 0);
    if (sendSock == INVALID_SOCKET)
        ErrorHanding("socket() error!");

    memset(&localBroadAddr, 0, sizeof(localBroadAddr));
    localBroadAddr.sin_family = AF_INET;
    localBroadAddr.sin_addr.s_addr = inet_addr(argv[1]);
    localBroadAddr.sin_port = htons(atoi(argv[2]));

    // 广播
    setsockopt(sendSock, SOL_SOCKET, SO_BROADCAST, (void *)&brd, sizeof(brd));

    FILE *fp = fopen("news.txt", "r");
    if (fp == NULL)
        ErrorHanding("fopen() error!");

    while (!feof(fp))
    {
        fgets(buf, BUF_SIZE, fp);
        sendto(sendSock, buf, strlen(buf), 0, (SOCKADDR *)&localBroadAddr, sizeof(localBroadAddr));
        Sleep(2000);
    }

    closesocket(sendSock);
    WSACleanup();

    return 0;
}

news_receiver_local_broad_win.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#define BUF_SIZE 30

void ErrorHanding(char *message)
{
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

int main(int argc, char *argv[])
{
    WSADATA wsaData;
    SOCKET recvSock;
    SOCKADDR_IN recvAddr;
    int strLen;
    char buf[BUF_SIZE];

    if (argc != 2)
    {
        printf("Usage: %s <port>\n", argv[0]);
        exit(1);
    }

    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        ErrorHanding("WSAStartup() error!");

    recvSock = socket(PF_INET, SOCK_DGRAM, 0);
    if (recvSock == INVALID_SOCKET)
        ErrorHanding("socket() error!");

    memset(&recvAddr, 0, sizeof(recvAddr));
    recvAddr.sin_family = AF_INET;
    recvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    recvAddr.sin_port = htons(atoi(argv[1]));

    if (bind(recvSock, (SOCKADDR *)&recvAddr, sizeof(recvAddr)) == SOCKET_ERROR)
        ErrorHanding("bind() error!");

    while (1)
    {
        strLen = recvfrom(recvSock, buf, BUF_SIZE - 1, 0, NULL, 0);
        if (strLen < 0)
            break;
        buf[strLen] = '\0';
        fputs(buf, stdout);
    }

    closesocket(recvSock);
    WSACleanup();

    return 0;
}

编译:

gcc news_sender_local_broad_win.c -lwsock32 -o newsSendLocalBroadWin
gcc news_receiver_local_broad_win.c -lwsock32 -o newsRecvLocalBroadWin

运行结果:

// 接收端
C:\Users\81228\Documents\Program\TCP IP Project\Chapter 14>newsRecvLocalBroadWin 9190
A powerful magnitude-7.7 earthquake struck central Myanmar on Friday, causing widespread devastation. The confirmed death toll from the earthquake has risen to 1,644.
// 发送端
C:\Users\81228\Documents\Program\TCP IP Project\Chapter 14>newsSendLocalBroadWin 255.255.255.255 9190

基于 Windows 的直接广播示例程序

前一小节的程序不用变,我们将本地广播地址改成自己主机的地址。

按下 win + R,输入 cmd,进入,输入 ipconfig 指令,就能找到自己主机的 IPv4 地址。

在这里插入图片描述

再次运行程序,修改发送端指定的发送 IP 地址为我们主机的地址。

运行结果:

// 接收端
C:\Users\81228\Documents\Program\TCP IP Project\Chapter 14>newsRecvLocalBroadWin 9190
A powerful magnitude-7.7 earthquake struck central Myanmar on Friday, causing widespread devastation. The confirmed death toll from the earthquake has risen to 1,644.
// 发送端
C:\Users\81228\Documents\Program\TCP IP Project\Chapter 14>newsSendLocalBroadWin 192.168.113.1 9190

多播 VS 广播

对比

  • 接收者范围: 广播发送给所有设备,而多播只发送给特定的组。
  • 网络效率: 多播比广播更高效,因为它减少了不必要的数据传输。
  • 地址类型: 广播使用广播地址,多播使用多播地址。
  • 适用场景: 广播适用于需要通知所有设备的场景,而多播适用于需要向特定群体发送数据的场景。

多播的使用场景

  1. 大规模数据分发: 股票市场信息、新闻更新或在线直播。
  2. 视频会议和在线教育
  3. IPTV和多媒体流
  4. 网络监控和安全
  5. 分布式计算
  6. 实时数据服务: 天气更新、交通信息或金融市场数据,可以多播给所有订阅服务的用户。

广播的使用场景

  1. 局域网内通信: 如打印作业请求或网络发现协议。
  2. 设备发现: 一些设备和服务使用广播来发现网络上的其他设备。
  3. 游戏和娱乐: 在局域网游戏或多媒体应用中,广播可以用于快速发现和连接游戏服务器或媒体播放设备。
  4. 紧急通知系统: 在某些情况下,可能需要向局域网内的所有设备发送紧急通知或警报。

习题

(1)TTL的含义是什么?请从路由器的角度说明较大的TTL值与较小的TTL值之间的区别及问题。

TTL是Time to Live的简写,意思是生存时间,是决定“数据包传递距离”的主要因素。

TTL的值设置过大将影响网络流量。当然,设置过小,也无法传递到目标。

(2)多播与广播的异同点是什么?请从数据通信的角度说明。

广播在“一次性向多个主机发送数据”这一点上与多播类似,但传输数据的范围有区别,多播即使在跨越不同网络的情况下,只要加入多播组就能接收数据,相反,广播只能向同一网络中的主机传输数据。

(3)下列关于多播的描述错误的是?

a. 多播是用来向加入多播组的所有主机传输数据的协议。
b. 主机连接到同一网络才能加入多播组,也就是说,多播组无法跨越多个网络。
c. 能够加入多播组的主机数并无限制,但只能有1个主机(Sender)向该组发送数据。
d. 多播时使用的套接字是UDP套接字,因为多播是基于UDP进行数据通信的。

答:b、c。

(4)多播也对网络流量有利,请比较TCP数据交换方式解释其原因。

若通过TCP向1000个主机发送文件,共需传递1000次,但此时若使用多播方式传输文件,则是需要发送1次,之后由路由器进行转发。

(5)多播方式的数据通信需要MBone虚拟网络。换言之, MBone是用于多播网络,但它是虚拟网络。请解释此处的“虚拟网络”。

“虚拟网络”是指一个不依赖于实际物理网络硬件的网络拓扑,它通过在现有物理网络上叠加逻辑结构和功能来实现特定目的。在多播通信中,MBone(Multicast Backbone)作为虚拟网络,起到了支持多播数据传输的作用。

具体来说,MBone的“虚拟网络”特性包含以下几点:

  1. 建立在现有的物理网络之上:
    MBone并不是一个独立的物理网络,而是通过软件配置和协议(如多播路由协议)在现有的IP网络(如互联网)中创建的逻辑网络。

  2. 逻辑拓扑:
    MBone使用一组支持多播的路由器(通常通过多播路由协议如 DVMRP 或 PIM)来构建虚拟链路。数据在这些逻辑链路之间传递,而不必依赖物理链路的具体布局。

  3. 多播组成员动态加入和离开:
    通过MBone,用户可以动态加入或离开一个多播组,这种灵活性由虚拟网络的逻辑实现,而不是由物理硬件决定。

  4. 支持多播流量的转发和优化:
    多播通常需要将一份数据高效地分发到多个目的地。MBone的虚拟网络通过在逻辑层次管理数据包的转发,避免了在物理网络中传输过多的冗余数据。

总结:MBone被称为虚拟网络,是因为它依赖现有的物理网络,通过软件和协议来构建支持多播通信的逻辑网络。它为多播通信提供了必要的基础设施,而无需物理网络的重新部署或重大改造。

《TCP/IP 网络编程》第 14 章——多播与广播(学习笔记) 代码链接 第 14 章 多播与广播 14.1 多播 多播(Multicast)方式的数据传输是基于 UDP 完成的。因此,与 UDP 服务器端/客户端的实现方式非常接近。区别在于,UDP 数据传输以单一目标进行,而多播数据同时传递到加入(注册)特定组的大量主机。换言之,采用多播方式时,可以同时向多个主机传递数据。 14.1.1 多播的数据传输方式及流量方面的优点 多播的数据传输特点可整理如下。 多播服务器端针对特定多播组,只发送 1 次数据。 即使只发送 1 次数据,但该组内的所有客户端都会接收数据 多播 阅读详情

相关推荐

HCIA-Storage 存储工程师学习笔记——1. 存储技术趋势

文章目录1. 存储技术趋势1.1 数据、信息与数据存储1.2 存储技术的发展①存储架构的发展②存储介质的发展③ 接口协议的发展1.3 存储产品的发展趋势 华为HCIA-Storage认证地址:https://e.huawei.com/cn/talent/#/cert/roadmap 1. 存储技术趋势 1.1 数据、信息与数据存储 什么是数据? ​ 数据是对所有事物的数字表示。 数据的种类? 结构化数据 半结构化数据 非结构化数据 数据的处理周期 ​ 数据处理是人或机器对数据进行的重组或重新排序,

超级大洋葱的博客 2847

TCP/IP——广播和多播(组播)

一、引言 三种IP地址:单播地址、广播地址和组播地址。广播和多播仅应用于UDP(因为TCP是端对端的连接,无法实现一对多)。 单播,一对一,目的地址是单个主机; 广播,一对全部,目的地址是局域网中的全部主机; 多播,一对部分,目的地址是局域网中的部分主机;广播也是多播的一种特殊形式,即目的地址为全部主机。 TCP是一个面向连接的协议,TCP一定是点对点的,一点是两个主机来建立连接的,TCP肯定是单...

weixin_44233369的博客 1万+

转载:YOLOv8改进全新Inner-IoU损失函数:扩展到其他SIoU、CIoU等主流损失函数,带辅助边界框的损失

目标检测是计算机视觉中的基本任务,包括目标分类和定位。边界框回归损失函数是检测器定位分支的重要组成部分,检测器的定位精度在很大程度上取决于边界框回归,在当前的检测器中发挥着不可替代的作用。在BBR中,IoU损失可以准确描述预测边界框与GT框之间匹配的程度,确保模型在训练过程中可以学习到目标的位置信息。作为现有主流边界框回归损失函数的基本部分,IoU定义如下:B和分别代表预测框和GT框。定义IoU之后,相应的损失可以定义如下:至今,基于IoU的损失函数逐渐成为主流并占据主导地位。

wuling129的专栏 4942

TCP/IP网络编程——多播与广播

TCP/IP网络编程——多播与广播

u011895157的博客 2021

基于STM32的智能循迹小车设计(基础版)

基于STM32的智能循迹小车设计 硬件准备 1、小车底盘+四直流电机(带轮) 2、STM32F103C8T6核心板 3、12V 8700mAh锂电池(可以用几节18650锂电池) 4、循迹模块 选择的是TCRT500L,五路集成在一起,集成度比较高,但是可能不如五个单独的循迹模块好用 5、L298N电机驱动模块 四驱车为啥用L298N电机驱动模块? 可以把左边的两个电机并联,用输出A控制。把右边的两个电机并联,用输出B控制。 12V供电接电源正极,供电GND接电源负极和核心板GND,5V供电接核心

Rendezvous1的博客 3万+

伺服电机入门01

编码器输出 旋转信号 , 接收端: 使用ADC 捕捉旋转信号 ,转成数字信号,驱动器得到数字处理, 因为信号量是模拟信号, mcu mpu 等芯片通常内部处理是数字,通过adc 得到数字cpu 才能识别 传输过来的pos 等信息。IPM 芯片示例, IRAM256A 这个芯片已经停产,有换新的,,下面示例来自stmbl 高功率方案,4 步进电机 有全步控制,半步控制 ,微步控制,FOC控制,步进电机也是可以做伺服系统的。以下面几种信号是可以细分,也就是通过细分增加编码器的分辨率,

qq_25160559的博客 969

《TCP/IP网络编程》(第十四章)多播与广播

当需要向多个用户发送多媒体信息时,如果使用TCP套接字,则需要维护与用户数量相等的套接字;如果使用之前学习的UDP,传输次数也需要和用户数量相同。所以为了解决这些问题,可以采用多播和广播技术,这样只需要,所有用户都能接收到信息。

立志成为炼丹师? 2052

药物对接仿真软件:HADDOCK_(5).HADDOCK中蛋白质-配体对接流程

半柔性能量最小化阶段是在刚体能量最小化的基础上,允许配体的部分柔性,通过优化配体的构象来进一步提高对接的准确性。半柔性能量最小化阶段是在刚体能量最小化的基础上,允许配体的部分柔性,通过优化配体的构象来进一步提高对接的准确性。如果是PDB格式,确保文件包含所有必要的原子信息。对接完成后,HADDOCK会生成一系列的输出文件,包括对接后的蛋白质-配体复合物结构文件、能量评分文件和统计分析文件。对接完成后,HADDOCK会生成一系列的输出文件,包括对接后的蛋白质-配体复合物结构文件、能量评分文件和统计分析文件。

kkchenjj的博客 1081

TCP/IP网络编程_第14章多播与广播

14.1 多播 多播(Multicast)方式的数据传输是基于UDP完成的. 因此, 与UDP服务器/客户端的实现方式非常接近. 区别在于, UDP数据传输以单一目标进行, 而多播数据同时传递到加入(注册)特定组的大量主机. 换言之, 采用多播方式时, 可以同时向多个主机传递数据. 多播的数据传输方式及流量方面的优点 多播的数据传输特点可整合如下. 多播组是D类IP地址(224.0.0.0 ~ 239.255.255.255), "加入多播组"可以理解为通过程序完成如下声明: 多播是基于UDP完成的,.

weifc-wei 的博客 773

【YOLOv8改进-注意力机制】LSKNet(Large Selective Kernel Network ):空间选择注意力

【YOLOv8改进-注意力机制】LSKNet(Large Selective Kernel Network ):空间选择注意力 (论文笔记+引入代码)。LSKNet能够动态调整其大的空间接收场,以更好地模拟遥感场景中各种对象的范围上下文。据我们所知,这是首次在遥感目标检测领域探索大型和选择性核机制。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 2864

GPU 运维实战:H100/H800/B300 换卡与压测

(烧多久、看什么、什么算合格)。文末还给了一个能直接跑的验收判定脚本,三个真实场景的裁决输出都在。

老韩的Linux云计算架构师进阶之路 271

网络编程——多播与广播

参考 《TCP/IP网络编程》 尹圣雨 多播与广播 多播 多播(Multicast)方式的数据传输是基于UDP完成的。与UDP服务器端/客户端的实现方式区别在于,UDP数据传输以单一目标进行,而多播数据同时传递传递到加入(注册)特定组的大量主机 MBone(Multicast Backbone,多播主干网) 多播是基于MBone这个虚拟网络工作的。虚拟网络可以理解为通过网络中的特殊协议工作的软件概念上的网络。即MBone并非可以触及的物理网络。它是以物理网络为基础,通过软件方法实现的多播通信必备虚拟网络

beilizhang的博客 2654

基于学术研究风云卫星数据下载教程

目录 一、相关网址 1.登录注册网址:国家卫星气象中心 2.风云数据服务客户端下载网址 3.风云卫星遥感数据服务网址 二、下载数据步骤 1.首先在注册登录网址,注册一个账户 2.待账户审核后,登录账户即可搜索并下载数据 三、相关工具下载 1.登录风云卫星遥感数据服务网址 2.NCSA HDFView软件 3.风云卫星数据(L1)处理软件包(FENGYUN Toolkit v1.1) 4.静止卫星云图分区图显示软件(SECView) 5.风云二号静止气象卫星数据及产品处理..

珞瑜的博客 1万+

《TCP/IP网络编程》第 14 章 多播与广播 笔记

第 14 章 多播与广播 本章代码,在TCP-IP-NetworkNote中可以找到。 14.1 多播 多播(Multicast)方式的数据传输是基于 UDP 完成的。因此 ,与 UDP 服务器端/客户端的实现方式非常接近。区别在于,UDP 数据传输以单一目标进行,而多播数据同时传递到加入(注册)特定组的大量主机。换言之,采用多播方式时,可以同时向多个主机传递数据。 14.1.1 多播的数据传输方...

riba2534的博客 1147

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

《TCP/IP网络编程》第14章 多播与广播

《TCP/IP网络编程》第14章多播TTL(Time to Live,生存时间)加入多播组实现多播广播广播方式修改套接字属性实现广播Windows实现 多播 多播(Multicast)基于UDP,UDP数据传输以单一目标进行,多播数据同时传递到加入(注册)特定组的大量主机(同时向多个主机传递数据)。 多播的数据传输特点: 多播服务器端针对特定多播组,只发送一次数据。 该组内所有客户端都会收到数据。 多播组数可在IP地址范围内任意增加。 加入特定组即可接收发往该多播组的数据。 多播组是D类IP地址(224

yxqq378287007的博客 582

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

《TCP/IP网络编程》Go语言系列 -- 多播与广播

多播中用「发送者」(以下称为 Sender) 和「接收者」(以下称为 Receiver)替代服务器端和客户端。顾名思义,此处的 Sender 是多播数据的发送主体,Receiver 是需要多播组加入过程的数据接收主体。下面是示例,示例的运行场景如下:...............

haoran的博客 1703

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

TCP/IP 网络编程:多播与广播

广播实现简单,但只限于局域网,且会打扰子网内所有主机;多播更高效、可控,能够跨路由器传播,但需要接收端主动加入多播组。在实际开发中,应根据业务范围与网络环境选择合适的方案:局域网内的设备发现可以优先考虑广播,而需要跨网段、面向特定群体的数据分发则应使用多播。

2601_96907930的博客 270

《TCP/IP网络编程》多播与广播-第14章

不同:多播可以跨网络传输,只传给加入某个多播组的主机,更具选择性和效率。相反,广播组只能在同一子网/局域网同一网络中传输,传送给该网络中的全部主机。“虚拟网络”意味着它不需要物理上的独立网络结构,而是通过软件隧道和特定协议(如 DVMRP、PIM)在现有网络中建立逻辑通路,实现多播通信。相同:都可以给多个主机传输相同数据报,并且发送端只需传输一次,然后由路由器进行复制发送多个主机,实现“一对多”通信。2多播对于加入多播组的主机均发送数据包,后加入的主机无法收到之前的信息,发送端无需重发数据。

2401_86994729的博客 524

《TCP/IP网络编程》课后练习答案1-14章

第一章 理解网络编程和套接字 套接字在网络编程中的作用是什么?为什么称它为套接字? P2,网络编程就是编写程序让两台联网的计算机相互交换数据。在我们不需要考虑物理连接的情况下,我们只需要考虑如何编写传输软件。操作系统提供了名为“套接字”,套接字是网络传输传输用的软件设备 socket英文原意是插座:我们把插头插到插座上就能从电网获得电力供给,同样,为了与远程计算机进行数据传输,需要连接到I...

baichaqinghuan的博客 9391

TCP/IP网络编程第14章多播与广播复习总结

关于多播 多播方式的数据传输时基于UDP完成的。 多播的数据传输特点: 多播服务器端针对特定多播组,只发送一次数据 该组内的所有客户端都会接收数据 多播组数可在IP地址范围内任意增加 加入特定组即可接收发往多播组的数据 说白了,多播就是指定了一个组,多播服务器端只需要发送一次数据给组内即可,然后这个数据报会借助路由器传递到该组内的所有主机。 多播主要用于多媒体的实时传输。毕竟人家UDP。 ...

博客周 231

Linux之广播和多播

最近学习Linux网络编程学到了广播与多播,就在这做点笔记。其中一些原理我就不介绍了,我觉得学习Linux网络编程,TCP/IP三卷还是基础,是需要好好看看。 广播的服务器端 : #include //#include #include #include #include #include #define BUFLEN 255 void getcurtime(char *cur

kejie1235的专栏 1134
上一篇: Leetcode 第 143 场双周赛题解
下一篇: 《TCP/IP网络编程》学习笔记 | Chapter 15:套接字与标准 I/O
UestcXiye
博客等级 码龄8年 9030粉丝 1306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值