什么是局域网多播介绍
通常把一对多的通信称为多播通信。采用多播通信技术,不仅可以实现一个发送者和多个接收者之间进行通信的功能,而且可以有效减轻网络通信的负担,避免资源的无谓浪费。
局域网多播工作原理
在现代公司、企业、教育机构、政府部门等构建的小型局域网络应用系统中,经常要在一台主机上把数据、消息、文件可靠地传送到其他在线的计算机上,在更高级的应用场合,还要在一台主机上对其他的站点计算机进行一对多的统一控制,比如开关机,发布统一操作指令等。这种一对多的通信方式,一般在通信协议上采用无连接、无确认的 UDP协议,在实现技术上可采用多播技术。共享式对等局域网由于各站资源取得机会具有均等的特性,采用 UDP 协议及多播技术具有应用简单,通信效率高的特点,多播技术既可以进行统一整体控制,也方便分组、分类进行控制与管理。
局域网多播技术简介
局域网多播定义
“多播”也称为“组播”,在分类集中控制、网上视频会议、网上视频点播特别适合采用多播方式。因为如果采用单播方式,逐个节点传输,有多少个目标节点,就会有多少次传送过程,这种方式虽然可靠,但效率极低,是不可取的;如果采用不区分目标、全部发送的广播方式,虽然一次可以传送完数据,但是显然达不到区分特定数据接收对象的目的。采用多播方式,既可以实现一次传送所有目标节点的数据,也可以达到只对特定对象传送数据的目的。
局域网多播地址
IP 采用 D 类地址来支持多播。每个 D 类地址代表一组主机。共有 28 位可用来标识小组。所以可以同时有多达 25亿个小组。当一个进程向一个 D 类地址发送分组时,会尽最大努力将它送给小组的所有成员,但不能保证全部送到,有些成员可能收不到这个分组。
局域网多播路由器
多播由特殊的多播路由器来实现,多播路由器同时也可以是普通路由器。各个多播路由器每分钟发送一个硬件多播信息给子网上的主机(目的地址为 244.0.0.1),要求它们报告其进程当前所属的是哪一组,各主机将它感兴趣的 D 类地址返回。
局域网多播软件实现
在实际应用中,编程人员通常需要自己编制底层网络应用程序来实现网上的底层通信,如具体实现 IP 多播通信的功能。编制底层网络应用程序通常要借助于网络数据通信编程接口,而在不同的操作系统中所提供的网络编程接口是有所不同的,如在 Microsoft Windows环境下的网络编程接口就是Windows套接字(Windows Socket,简称 Winsock)。
Winsock 提供了包括TCP/IP、IPX等多种通信协议下的编程接口。不同的 Windows 版本支持不同的 Winsock 版本,本控制软件系统使用 Winsock 2.0 版本,实现 IP 多播的步骤如下:
1、初始化 Winsock 资源
在使用 Winsock 之前,必须调用 WSAStartup()函数初始化 Windows Sockets DLL。它允许应用程序或 DLL 指定Windows Sockets API 要求的版本。
if( WSAStartup( MAKEWORD(2,2),&wsd) != 0 ) { printf(\"WSAStartup() failedn\"); return ; }
2、创建套接字
调用 WSASocket()函数可以创建一个使用 UDP 协议的套接字,它是加入多播组的初始化套接字,并且以后数据的发送和接收都在该套接字上进行。
if((sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET){ WSACleanup(); return ; }
3、绑定套接字
调用 bind()函数绑定套接字,从而将创建好的套接字与本地地址和本地端口联系起来。对于多播通信来说,发送和接收数据通常采用同一个端口。
local.sin_family = AF_INET;local.sin_port = htons(MCASTPORT);local.sin_addr.s_addr = INADDR_ANY;if( bind(sock,(struct sockaddr*)&local,sizeof(local)) ==SOCKET_ERROR ){ closesocket(sock); WSACleanup(); return ; }
4、 加入多播组
可以采用以下方式加入多播组。
remote.sin_family = AF_INET;remote.sin_port = htons(MCASTPORT);remote.sin_addr.s_addr = inet_addr( MCASTADDR );while(( sockM = WSAJoinLeaf(sock,(SOCKADDR*)&remote,sizeof(remote),NULL,NULL,NULL,NULL, JL_BOTH)) == INVALID_SOCKET)
5、数据的广播
void txfs(TCHAR *sendbuf){ sendto(sockM,(char*)sendbuf,1024,0,(struct sockaddr*)&remote,sizeof(remote)); }
6、数据的接收
UINT txjs(LPVOID param){ recvfrom(sock,recvbuf,BUFSIZE,0,(struct sockaddr*)&from,&len); }