广播和组播

本文详细介绍了网络通信中的广播和组播方式,包括其原理、实现方法及应用场景。通过具体代码示例展示了如何在本地子网上发送广播数据和在互联网上进行组播通信。广播适用于本地网络中的数据广播需求,而组播则用于多点传输,特别是在互联网环境中。文章还提供了接收广播和组播数据的代码,并解释了如何配置多播地址和TTL值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

套接字除了单播通信(点对点外),还有广播和组播通信两种工作方式。

一、   广播

利用广播可以将数据发送到本地子网上的每个机器。广播的缺点是如果多个进程都发送广播数据,网络就会阻塞。为了进行广播,必须打开广播选项SO_BROADCAST,然后用recvfrom,sendto等函数收发广播数据。

对于UDP来说,存在一个特定的广播地址—255.255.255.255,广播数据都应该发送到这里。理论上讲,可以在整个Internet发送广播数据,但是几乎没有路由器转发广播数据,所以,广播程序只能应用在本地子网中。

发送端代码如下:

#include "stdafx.h"
#include "stdio.h"
#include <windows.h>
#pragma comment(lib, "WS2_32")
int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2, 2);
	if(WSAStartup(sockVersion, &wsaData) != 0)
	{
		return 0;
	}

	SOCKET s=socket(AF_INET,SOCK_DGRAM,0);//创建UDP
	//有效的SO_BROADCAST 选项
	BOOL bBroadcast=TRUE;
	setsockopt(s,SOL_SOCKET,SO_BROADCAST,(char*)&bBroadcast,sizeof(BOOL));
	//设置广播地址
	SOCKADDR_IN bcast;
	bcast.sin_family=AF_INET;
	bcast.sin_addr.s_addr=INADDR_BROADCAST;//inet_addr("255.255.255.255");
	bcast.sin_port=htons(4567);
	//发送广播
	printf("开始向4567端口发送数据……\n\n");
	char sz[]="This is just a test.\r\n";
	while(TRUE)
	{
		sendto(s,sz,strlen(sz),0,(sockaddr*)&bcast,sizeof(bcast));
		Sleep(5000);
	}

	WSACleanup();	
	return 0;
}

接收端代码如下:

#include "stdafx.h"
#include "stdio.h"
#include <windows.h>
#pragma comment(lib, "WS2_32")
int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2, 2);
	if(WSAStartup(sockVersion, &wsaData) != 0)
	{
		return 0;
	}

	SOCKET s=socket(AF_INET,SOCK_DGRAM,0);//创建UDP	
	
	SOCKADDR_IN bcast;
	bcast.sin_family=AF_INET;
	bcast.sin_addr.s_addr=INADDR_ANY;
	bcast.sin_port=ntohs(4567);
	
	if(bind(s,(sockaddr*)&bcast,sizeof(bcast))==SOCKET_ERROR)
	{
		printf("bind() failed\n");
		return 0;
	}

	//接收广播
	printf("开始在4567端口接收广播数据……\n\n");
	SOCKADDR_IN addrRemote;
	int nLen=sizeof(addrRemote);
	char sz[256];
	while(TRUE)
	{
		int nRet=recvfrom(s,sz,256,0,(sockaddr*)&addrRemote,&nLen);
		if(nRet>0)
		{
			sz[nRet]='\0';
			printf(sz);
		}
	}

	WSACleanup();	
	return 0;
}

二、组播通信

    在internet中多点传输一般使用组播通信。

#include "stdafx.h"
#include "stdio.h"

#include "MultiSock.h"
int _tmain(int argc, _TCHAR* argv[])
{
	CMultiSock mySock;
	mySock.RecvPacket();	
	return 0;
}

#pragma once
#include <Ws2tcpip.h>
#include <windows.h>
#pragma comment(lib, "WS2_32")
class CMultiSock
{
public:
	CMultiSock(void);
	~CMultiSock(void);
	DWORD m_dwMultiAddr;	// 此组使用的多播地址
	USHORT m_port;
	SOCKET s;               //套接字
	sockaddr_in si;
	void RecvPacket(void);
};

#include "StdAfx.h"
#include "MultiSock.h"

CMultiSock::CMultiSock(void)
{
	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2, 2);
	if(WSAStartup(sockVersion, &wsaData) != 0)
	{
		return;
	}
	s = socket(AF_INET, SOCK_DGRAM, 0);

	// 允许其它进程使用绑定的地址
	BOOL bReuse = TRUE;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&bReuse, sizeof(BOOL));
	m_dwMultiAddr=inet_addr("234.5.6.7");//组播的IP地址;
	m_port=4567;

	// 绑定到4567端口	
	si.sin_family = AF_INET;
	si.sin_port = ntohs(m_port);
	si.sin_addr.S_un.S_addr = INADDR_ANY;
	bind(s, (sockaddr*)&si, sizeof(si));	

	
	//设置多播TTL值
	int nTTL=64;	
	int nRet=setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL,(char*)&nTTL,sizeof(nTTL));
	if(nRet==SOCKET_ERROR)
	{
		return;
	}
	
	/*
	//设置要使用的发送接口
	in_addr addr;//=INADDR_ANY;
	nRet=setsockopt(s,IPPROTO_IP,IP_MULTICAST_IF,(char*)&addr,sizeof(addr));
	if(nRet==SOCKET_ERROR)
	{
		return;
	}
	*/

	// 加入多播组
	ip_mreq	mcast;
	mcast.imr_interface.S_un.S_addr = INADDR_ANY;
	mcast.imr_multiaddr.S_un.S_addr = m_dwMultiAddr;  // 多播地址为234.5.6.7
	setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&mcast, sizeof(mcast));	
	
	//发送加入组消息
	sockaddr_in sRemote;
	sRemote.sin_family=AF_INET;
	sRemote.sin_port=htons(m_port);
	sRemote.sin_addr.S_un.S_addr=m_dwMultiAddr;	
	int ret=sendto(s,"Join this party\r\n",strlen("Join this party\r\n"),0,(sockaddr*)&sRemote,sizeof(sRemote));
	
}

CMultiSock::~CMultiSock(void)
{
	
	//发送加入组消息
	sockaddr_in sRemote;
	sRemote.sin_family=AF_INET;
	sRemote.sin_port=htons(m_port);
	sRemote.sin_addr.S_un.S_addr=m_dwMultiAddr;	
	sendto(s,"Leave this party\r\n",strlen("Leave this party\r\n"),0,(sockaddr*)&sRemote,sizeof(sRemote));

	ip_mreq mcast;
	mcast.imr_interface.S_un.S_addr=INADDR_ANY;//加入组的IP地址
	mcast.imr_multiaddr.S_un.S_addr=m_dwMultiAddr;
	setsockopt(s,IPPROTO_IP,IP_DROP_MEMBERSHIP,(char*)&mcast,sizeof(mcast));
	
	WSACleanup();	
}

void CMultiSock::RecvPacket(void)
{	
	
	// 接收多播组数据
	printf(" 开始接收多播组234.5.6.7上的数据... \n");
	char buf[1280];
	int nAddrLen = sizeof(si);
	while(TRUE)
	{
		int nRet = ::recvfrom(s, buf, strlen(buf), 0, (sockaddr*)&si, &nAddrLen);
		if(nRet != SOCKET_ERROR)
		{
			buf[nRet] = '\0';
			printf(buf);
		}
		else
		{
			int n = ::WSAGetLastError();
			break;
		}
	}
	
		
}





<think>嗯,用户现在想了解广播地址地址的区别以及它们的用法。根据用户提供的引用内容,我需要先整理一下相关的知识点。首先,用户提到了单广播、多)地址的区别,还有MAC地址如何区分单广播。我需要确保正确理解这些概念,然后对比广播的不同之处。 首先,广播地址地址都属于一种发送到多个接收者的地址类型,但具体应用场景机制不同。根据引用[1],多地址的范围是224.0.0.0到239.255.255.255,而广播地址通常指的是本地网络中的所有设备,比如IP中的255.255.255.255或者MAC地址全为FF的地址。引用[3]中提到MAC地址的第一个字节最低位是0是单,1是,而广播地址的MAC是FFFF.FFFF.FFFF。 接下来需要明确两者的定义。广播地址是发送到同一网络内的所有设备,而地址则是发送到加入特定的一设备。比如,广播地址用于ARP请求,而用于视频会议或流媒体传输,这样只有加入的设备才会处理数据。 然后要考虑它们的应用场景。广播地址适用于需要所有设备接收的情况,比如DHCP或ARP,但可能会造成网络拥堵。而更高效,适用于需要同时传输到多个但非所有设备的场景,比如IPTV,这样减少了不必要的流量。 另外,地址范围MAC地址的转换也是重点。根据引用[2],D类地址是,而广播地址在IPv4中是特定的。MAC地址方面,广播是全F,则是首字节最低位为1,例如01:00:5E开头的MAC对应IPv4地址。 可能还需要提到两者的优缺点,比如广播的简单但效率低,的复杂但节省带宽。同时,用户之前的问题涉及CSMA/CD,可能与广播的使用有关联,比如冲突域中的广播流量影响。 需要确保回答结构清晰,分点列出定义、地址范围、MAC地址结构、应用场景优缺点,并引用提供的资料作为支持。最后生成相关问题,帮助用户深入理解。</think>### 广播地址与地址的区别及用法 广播地址地址均用于向多个接收者发送数据,但设计目标应用场景有本质差异。以下是两者的核心区别及典型用法: --- #### **1. 定义与目标范围** - **广播地址** - **定义**:指向同一网络内的所有设备(无论是否属于特定)。 - **目标范围**:强制所有设备接收数据,即使设备不需要该数据。 - **典型地址**: - **IPv4广播地址**:`255.255.255.255`(受限广播)或子网广播地址(如`192.168.1.255`)[^1]。 - **MAC广播地址**:`FF:FF:FF:FF:FF:FF`[^3]。 - **地址(多地址)** - **定义**:指向加入特定的一设备(仅成员接收数据)。 - **目标范围**:仅成员处理数据,非成员直接忽略。 - **典型地址**: - **IPv4地址**:D类地址(`224.0.0.0`~`239.255.255.255`),例如`224.0.0.1`表示本地网络中所有支持的主机[^2]。 - **MAC地址**:首字节最低二进制位为`1`,例如`01:00:5E:XX:XX:XX`(IPv4的固定前缀)[^3]。 --- #### **2. 地址结构与分配规则** - **广播地址** - **IPv4**:通过子网掩码计算得出(如`192.168.1.0/24`的广播地址为`192.168.1.255`)。 - **MAC**:固定为全`F`的地址,无动态分配机制。 - **地址** - **IPv4**:由IANA分层分配: - `224.0.0.0`~`224.0.0.255`:预留协议使用(如OSPF的`224.0.0.5`)[^2]。 - `224.0.1.0`~`238.255.255.255`:全局有效地址(如流媒体服务)。 - `239.0.0.0`~`239.255.255.255`:本地管理地址(需手动配置)[^2]。 - **MAC**:通过算法将IPv4地址映射到MAC地址。 - **映射规则**:取IPv4地址的后23位,填充到`01:00:5E:00:00:00`的后3字节中。 - 例如,IPv4地址`239.255.0.1`的MAC地址为`01:00:5E:7F:00:01`[^3]。 --- #### **3. 应用场景** - **广播地址** - **网络发现**:如ARP协议通过广播解析IP对应的MAC地址。 - **配置分发**:DHCP服务器通过广播分配IP地址。 - **缺点**:易引发广播风暴,导致网络拥塞。 - **地址** - **高效传输**:适用于视频会议(如Zoom)、IPTV直等需同时发送到多个接收者的场景。 - **路由协议**:如OSPF使用地址`224.0.0.5`同步路由表。 - **优点**:减少冗余流量,仅成员处理数据[^1][^2]。 --- #### **4. 关键区别总结** | **特性** | **广播地址** | **地址** | |------------------|---------------------------|---------------------------| | **目标设备** | 同一网络内所有设备 | 特定成员 | | **地址分配** | 固定或子网计算 | IANA分层分配 | | **网络效率** | 低(强制所有设备接收) | 高(仅成员接收) | | **典型协议** | ARP、DHCP | OSPF、PIM、流媒体协议 | --- ### 相关问题 1. 如何将IPv4地址映射到MAC地址? 2. 广播风暴是如何形成的?如何避免? 3. 协议(如IGMP)如何管理成员关系? 4. 为什么无线网络通常使用CSMA/CA而非CSMA/CD? [^1]: 引用自站内内容《单广播地址以及IP与MAC间的换算》。 [^2]: 引用自站内内容《IANA对D类地址的分配规则》。 [^3]: 引用自站内内容《如何区分MAC地址类型》。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值