组播通信C++ 代码实现

组播定义:组播技术是IP网络数据传输三种方式之一,在介绍Ip组播技术之前,先对IP网络数据传输的单播、组播和广播方式做一个简单的介绍。

单播:

     在发送者和每一接收者之间实现点对点网络 连接。如果一台发送者的接收者同时给多个的接收者传输相同的数据,也必须相应的复制多份的相同数据包。如果有大量主机希望获得数据包的同一份拷贝时,将导致发送者负担沉重、延迟长、网络阻塞、为保证一定的服务质量需要增加硬件和带宽。

广播:

   广播指在IP子网内广播数据包,所有子子网内部的主机将收到这些数据包。广播意味着网络向子网每一个主机都投递一份数据包,不论这些主机是否乐于接收该数据包。所以广播的使用范围非常小, 只在本地子网内有效,通过路由器和网络设备控制广播传输。

组播:

   组播在发送者和每一个接收者之间实现点对点网络连接。如果 一台发送者同时给多个接收者传输相同的数据,也只需复制一份相同的数据包。它提高了数据传送效率,减少了骨干网络出现拥塞的可能性。

 

服务端代码:

#include "stdafx.h"
#include <WinSock2.h>
#include <ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")

//#define MCAST_POPT 8888
#define MCAST_PORT 4098
#define MCAST_ADDR "224.0.1.88"
#define LOCAL_ADDR "127.0.0.1"
#pragma pack(1)
//...
#pragma pop()


int _tmain(int argc, _TCHAR* argv[])
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD( 2, 0 );

	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		printf("error\n");
		return -1;
	}

	if ( LOBYTE( wsaData.wVersion ) != 2 ||
		HIBYTE( wsaData.wVersion ) != 0 ) {
			WSACleanup( );
			printf("error\n");
			return -1; 
	}
	char Name[255];//定义用于存放获得的主机名的变量 
	char *IP;//定义IP地址变量 
	//CString strIP="";
	PHOSTENT hostinfo;
	if(gethostname (Name, sizeof(Name)) == 0)
	{ 
		//如果成功地将本地主机名存放入由name参数指定的缓冲区中 
		if((hostinfo = gethostbyname(Name)) != NULL) 
		{ 
			//这是获取主机名,如果获得主机名成功的话,将返回一个指针,指向hostinfo,hostinfo 
			//为PHOSTENT型的变量,下面即将用到这个结构体 
			IP = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list);
			while(*hostinfo->h_addr_list !=NULL)
			{
				printf("IP::%s\n",inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list++));
			}
			//trIP.Format(IP);
		}
	}
	printf("IP:%s\n",IP);
	//IP ="127.0.0.1";
	SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
	SOCKADDR_IN addrSrv;
	
	addrSrv.sin_family=AF_INET;
	addrSrv.sin_port=htons(MCAST_PORT);
	//addrSrv.sin_addr.S_un.S_addr= inet_addr(LOCAL_ADDR);
	addrSrv.sin_addr.S_un.S_addr= inet_addr(IP);//INADDR_ANY
	bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
	bool loop = 1;
	err = setsockopt(sockSrv,IPPROTO_IP,IP_MULTICAST_LOOP,reinterpret_cast<char FAR*>(&loop),sizeof(loop));

	struct ip_mreq mreq;
	mreq.imr_multiaddr.S_un.S_addr = inet_addr(MCAST_ADDR);
	mreq.imr_interface.s_addr = inet_addr(IP);
	err = setsockopt(sockSrv,IPPROTO_IP,IP_ADD_MEMBERSHIP,reinterpret_cast<char FAR*>(&mreq),sizeof(mreq));

	SOCKADDR_IN addrClient;
	int len=sizeof(SOCKADDR);
	char recvBuf[100];
	int recvLen = 0;
	int nCount = 10000;
	//CommData m_data;
	while(nCount--){
		memset(recvBuf,0,sizeof(recvBuf));
		if( (recvLen = recvfrom(sockSrv,recvBuf,dateSize,0,(SOCKADDR*)&addrClient,&len))!=-1){		
			printf("接收端口:%d ->%s已经连接上\r\n",addrClient.sin_port,inet_ntoa(addrClient.sin_addr));
			memcpy(&m_data,recvBuf,recvLen);
		}else
		{
			printf("wait....%d\n",10000 - nCount);
		}
		Sleep(10);
	}
	err = setsockopt(sockSrv,IPPROTO_IP,IP_DROP_MEMBERSHIP,reinterpret_cast<char FAR*>(&mreq),sizeof(mreq));
	closesocket(sockSrv);
	WSACleanup();
	getchar();
	return 0;
}

客户端代码:

#include<Winsock2.h>

#pragma  comment(lib,"ws2_32")
#define MCAST_PORT 8888
#define MCAST_ADDR "224.0.1.88" //组播地址


int _tmain(int argc, _TCHAR* argv[])
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD( 2, 0 );

	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		return -1;
	}

	if ( LOBYTE( wsaData.wVersion ) != 2 ||
		HIBYTE( wsaData.wVersion ) != 0 ) {
			WSACleanup( );
			return -1; 
	}
	SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
	SOCKADDR_IN addrSrv;
	bool opt = 1;
	setsockopt(sockClient,SOL_SOCKET,SO_BROADCAST,reinterpret_cast<char FAR*>(&opt),sizeof(opt));

	addrSrv.sin_family=AF_INET;
	addrSrv.sin_addr.S_un.S_addr=inet_addr(MCAST_ADDR);	
	addrSrv.sin_port=htons(MCAST_PORT);
	int n=20;
	while(n--){
	sendto(sockClient,"11000",strlen("11111"),0,
		(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
	}
	closesocket(sockClient);
	WSACleanup();
	getchar();
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值