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

📄 cmulticastadmin.cpp

📁 最近在学习directshow, Directshow实务精选的源代码
💻 CPP
字号:
//
// CMulticastAdmin.cpp
// 

/*-----------------------------------------------------*\
			HQ Tech, Make Technology Easy!       
 More information, please go to http://hqtech.nease.net.
/*-----------------------------------------------------*/

#include "stdafx.h"
#include "CMulticastAdmin.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
CMulticastAdmin::CMulticastAdmin()
{
	mSckReceiver   = INVALID_SOCKET;
	mMulticaster   = INVALID_SOCKET;
	// Multicast IP: from 224.0.0.0 to 239.255.255.255
	mMulticastIP   = 0xef080808;  // 239.8.8.8
	mMulticastPort = 10018;

	mIsReceiving = FALSE;
	mRcvThread   = NULL;
}

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

void CMulticastAdmin::SetMulticastIP(DWORD inIP)
{
	mMulticastIP = inIP;
}

DWORD CMulticastAdmin::GetMulticastIP(void)
{
	return mMulticastIP;
}

void CMulticastAdmin::SetMulticastIP(const char * inIP)
{
	mMulticastIP = ntohl(inet_addr(inIP));
}

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

void CMulticastAdmin::SetMulticastPort(WORD inPort)
{
	mMulticastPort = inPort;
}

WORD CMulticastAdmin::GetMulticastPort(void)
{
	return mMulticastPort;
}

BOOL CMulticastAdmin::CreateMulticaster(void)
{
	DeleteMulticaster();

	// Init WinSock
	WSADATA   data;
	int ret = WSAStartup(0x0202, &data);
	if (ret != 0)
	{
		WSACleanup();
		return FALSE;
	}

	// Get a datagram socket
	mMulticaster = socket(AF_INET, SOCK_DGRAM, 0);
	if (mMulticaster == INVALID_SOCKET)
	{
		WSACleanup();
		return FALSE;
	}

	/*  Avoid (WSA)EADDRINUSE error on bind() (last one to bind should 
	 *  receive dgrams sent to our port, but there are no guarantees of 
     *  this, unfortunately). */ 
	BOOL flag = TRUE;
	ret = setsockopt(mMulticaster, SOL_SOCKET, SO_REUSEADDR, 
		(char *)&flag, sizeof(flag));

	// Bind the socket
	SOCKADDR_IN addr;
	ZeroMemory(&addr, sizeof(addr));
	addr.sin_family      = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;   // don't care about NIC we're bound to
	addr.sin_port        = htons(mMulticastPort); // want data on this UDP port
	ret = bind(mMulticaster, (struct sockaddr*) &addr, sizeof(addr));

	return TRUE;
}

void CMulticastAdmin::DeleteMulticaster(void)
{
	if (mMulticaster != INVALID_SOCKET)
	{
		closesocket(mMulticaster);
		mMulticaster = INVALID_SOCKET;
		WSACleanup();
	}
}

BOOL CMulticastAdmin::CreateReceiver(void)
{
	DeleteReceiver();

	// Init WinSock
	WSADATA   data;
	int ret = WSAStartup(0x0202, &data);
	if (ret != 0)
	{
		WSACleanup();
		return FALSE;
	}

	// Get a datagram socket
	mSckReceiver = socket(AF_INET, SOCK_DGRAM, 0);
	if (mSckReceiver == INVALID_SOCKET)
	{
		WSACleanup();
		return FALSE;
	}

	// Setup on the socket
	BOOL flag = TRUE;
	ret = setsockopt(mSckReceiver, SOL_SOCKET, SO_REUSEADDR, 
		(char *) &flag, sizeof(flag));

	// Bind the socket
	SOCKADDR_IN addr;
	ZeroMemory(&addr, sizeof(addr));
	addr.sin_family      = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;   // don't care about NIC we're bound to
	addr.sin_port        = htons(mMulticastPort); // want data on this UDP port
	ret = bind(mSckReceiver, (struct sockaddr*) &addr, sizeof(addr));

	// Join the multicast group (for receiving)
	struct ip_mreq mreq; 
	mreq.imr_multiaddr.s_addr = htonl(mMulticastIP);
	mreq.imr_interface.s_addr = INADDR_ANY;
	ret = setsockopt(mSckReceiver, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
		(char *) &mreq, sizeof(mreq));

	return TRUE;
}

void CMulticastAdmin::DeleteReceiver(void)
{
	if (mSckReceiver != INVALID_SOCKET)
	{
		closesocket(mSckReceiver);
		mSckReceiver = INVALID_SOCKET;
		WSACleanup();
	}
}

// Sending methods
BOOL CMulticastAdmin::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(mMulticastIP);
	addr.sin_port        = htons(mMulticastPort);

	int val = sendto(mMulticaster, inBuffer, inLength, 0, 
		(sockaddr *) &addr, sizeof(addr));
	return (val != SOCKET_ERROR);
}

// Receiving methods
BOOL CMulticastAdmin::StartReceiving(void)
{
	// Create socket if necessary
	if (mSckReceiver == INVALID_SOCKET)
	{
		CreateReceiver();
	}

	if (mSckReceiver != INVALID_SOCKET)
	{
		if (mIsReceiving)
		{
			return TRUE;
		}
		
		DWORD threadID = 0;
		mRcvThread = CreateThread(NULL, 0, ReceivingThrd, 
			this, 0, &threadID);
		return (mRcvThread != NULL);
	}
	return FALSE;
}

void CMulticastAdmin::StopReceiving(void)
{
	if (mIsReceiving)
	{
		DeleteReceiver();
		// Make sure the receiving thread has been terminated 
		if (mRcvThread != NULL) 
		{
			WaitForSingleObject(mRcvThread, INFINITE);
			mRcvThread = NULL;
		}
	}
}

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

void CMulticastAdmin::ReceivingLoop(void)
{
	// Just for demo!
	struct sockaddr_in  addr_cli;
	int  addr_cli_len = sizeof(addr_cli);
	char buffer[1024];
	long bytes = 0;

	mIsReceiving = TRUE;
	while (mIsReceiving)
	{				
		int addr_cli_len = sizeof(addr_cli);
		bytes = recvfrom(mSckReceiver, (char *)buffer, 1024, 0,
			(LPSOCKADDR) &addr_cli, (int *) &addr_cli_len);
		if (bytes == SOCKET_ERROR ||
			bytes == 0)
		{
			mIsReceiving = FALSE;
		}
		else
		{
			buffer[bytes] = '\0';
			char *  pStr  = inet_ntoa(addr_cli.sin_addr);
			// Pop up a message box
			CString msg;
			msg.Format("Current PID: %d\nReceive from %s \nContent:%s", 
				GetCurrentProcessId(), pStr, buffer);
			AfxMessageBox(msg);
		}
	}
}

⌨️ 快捷键说明

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