⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketmul.cpp

📁 组拨技术
💻 CPP
字号:
// SocketMul.cpp: implementation of the CSocketMul class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SocketMul.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSocketMul::CSocketMul()
{
	m_multicaster = INVALID_SOCKET;	
	m_multicastPort = 10018;
	m_multicastIP = 0xef080808;		//239.8.8.8,范围224.0.0.0---239.255.255.255
	m_sckReceiver = INVALID_SOCKET;	
	m_bReceiving = false;
	m_rcvThread = NULL;
}

CSocketMul::~CSocketMul()
{
	DeleteMulticaster();
	DeleteReceiver();
	StopReceiving();
}

bool CSocketMul::CreateMulticaster()
{
	DeleteMulticaster();

	//初始化
	WSADATA data;
	int ret = WSAStartup( 0x0202,&data );
	if( ret != 0 )
	{
		WSACleanup();
		return false;
	}
	//创建UDPSOCKET
	m_multicaster = socket( AF_INET,SOCK_DGRAM,0 );
	if( m_multicaster == INVALID_SOCKET )
	{
		WSACleanup();
		return false;
	}

	//设置SOCKET参数,允许地址复用
	bool flag = true;
	ret = setsockopt( m_multicaster,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag) );
	//绑定SOCKET到组播端口号上
	SOCKADDR_IN addr;
	ZeroMemory( &addr,sizeof(addr) );
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;	//不关心网卡地址
	addr.sin_port = htons( m_multicastPort );
	ret = bind( m_multicaster,( struct sockaddr* )&addr,sizeof(addr) );
 

	return true;
}


bool CSocketMul::CreateReceiver()
{
	DeleteReceiver();

	WSADATA data;
	int ret  = WSAStartup( 0x0202,&data );
	if( ret != 0 )
	{
		WSACleanup();
		return false;
	}

	m_sckReceiver = socket( AF_INET,SOCK_DGRAM,0 );
	if( m_sckReceiver == INVALID_SOCKET )
	{
		WSACleanup();
		return false;
	}

	//设置socket参数,允许地址复用
	bool flag = true;
	ret = setsockopt( m_sckReceiver,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag) );

	int iError =  WSAGetLastError();


	//绑定SOCKET到组播端口上
	SOCKADDR_IN addr;
	ZeroMemory( &addr,sizeof(addr) );
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons( m_multicastPort );
	ret = bind( m_sckReceiver,(sockaddr*)&addr,sizeof(addr) );
	//将SOCKET加入到组播组(以接收组播数据)
	struct ip_mreq mreq;
	mreq.imr_multiaddr.s_addr = htonl(m_multicastIP);
	mreq.imr_interface.s_addr = INADDR_ANY;
	ret = setsockopt( m_sckReceiver,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&mreq,sizeof(mreq) );
	return true;
}




void CSocketMul::DeleteMulticaster()
{
	if( m_multicaster != INVALID_SOCKET )
	{
		closesocket( m_multicaster );
		m_multicaster = INVALID_SOCKET;
		WSACleanup();
	}
}

void CSocketMul::DeleteReceiver()
{
	if( m_sckReceiver != INVALID_SOCKET )
	{
		closesocket( m_sckReceiver );
		m_sckReceiver = INVALID_SOCKET;
		WSACleanup();
	}
}

void CSocketMul::StopReceiving()
{
	if( m_bReceiving )
	{
		DeleteReceiver();		//销毁,使接收函数失败或脱离阻塞

		if( m_rcvThread != NULL )
		{
			WaitForSingleObject( m_rcvThread,INFINITE );
			m_rcvThread = NULL;
		}

	}
}

//组播发送数据
bool CSocketMul::Multicast( const char * inBuffer,long inLength )
{
	SOCKADDR_IN addr;
	memset( (char*)&addr,0,sizeof(addr) );
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(m_multicastIP);
	addr.sin_port = htons(m_multicastPort);
	//向组播IP,PROT发数据
	int val = sendto( m_multicaster,inBuffer,inLength,0,(sockaddr*)&addr,sizeof(addr) );
	return ( val!= SOCKET_ERROR );
}

//启动数据接收线程
bool CSocketMul::StartReceiving( void )
{
	if( m_sckReceiver == INVALID_SOCKET )
	{
		CreateReceiver();
	}

	if( m_sckReceiver != INVALID_SOCKET )
	{
		if( m_bReceiving )
		{
			return true;
		}
		DWORD threadID = 0;
		m_rcvThread = CreateThread( NULL,0,ReceivingThrd,this,0,&threadID );
		return ( m_rcvThread != NULL );
	}
	return false;
}


DWORD WINAPI CSocketMul::ReceivingThrd( void * pParam )
{
	ASSERT( pParam );
	CSocketMul * pController = (CSocketMul *)pParam;
	pController->ReceivingLoop();
	return 0;
}

void CSocketMul::ReceivingLoop( )
{
	struct sockaddr_in addr_cli;
	char buffer[1024];
	long bytes = 0;
	m_bReceiving = true;
	int addr_cli_len =  sizeof(addr_cli);

	while( m_bReceiving )
	{
		bytes = recvfrom( m_sckReceiver,(char *)buffer,1024,0,(LPSOCKADDR)&addr_cli,(int *)&addr_cli_len );
		if( bytes == SOCKET_ERROR || bytes == 0 )
		{
			m_bReceiving = false;
		}
		else
		{
			buffer[bytes] = '\0';
			char * pStr = inet_ntoa(addr_cli.sin_addr);
			CString msg;
			msg.Format(_T("Current PID: %d\nReceive from %s \nContent:%s"),GetCurrentProcessId(),pStr,buffer);
			AfxMessageBox(msg);
		}
	}
}



void CSocketMul::SetMulticastIP( DWORD inIP )
{
	m_multicastIP = inIP;
}


DWORD CSocketMul::GetMulticastIP( )
{
	return m_multicastIP;
}


void CSocketMul::SetMulticastIP( const char * inIP )
{
	m_multicastIP = ntohl(inet_addr(inIP));
}


void CSocketMul::GetMulticastIP( char * outIP )
{
	if( outIP )
	{
		struct in_addr in;
		in.S_un.S_addr = htonl(m_multicastIP);
		char * pStr = inet_ntoa(in);
		strcpy( outIP,pStr );
	}
}

void CSocketMul::SetMulticastPort( WORD inPort )
{
	m_multicastPort = inPort;
}

DWORD CSocketMul::GetMulticastPort( )
{
	return m_multicastPort;
}
















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -