www.pudn.com > UdpMulticast.rar > MultiCast.cpp


// MultiCast.cpp: implementation of the CMultiCast class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "UdpMulticast.h" 
#include "MultiCast.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CMultiCast::CMultiCast() 
{ 
	m_hWnd = NULL; 
	m_bConnected = FALSE; 
	m_sockRecv = INVALID_SOCKET; 
	m_sockGroup = INVALID_SOCKET; 
} 
 
CMultiCast::~CMultiCast() 
{ 
 
} 
 
BOOL CMultiCast::InitInstance() 
{ 
	WSADATA wsadata; 
	if(WSAStartup(0x0202, & wsadata) != 0) 
	{ 
		TRACE("ERROR : InitInstance !\n"); 
		return FALSE;  
	} 
	return TRUE; 
} 
 
BOOL CMultiCast::UninInstance() 
{ 
	if(WSACleanup() != 0) 
	{ 
		TRACE("ERROR : UninInstance - %d .\n", WSAGetLastError()); 
		return FALSE; 
	} 
	return TRUE; 
} 
 
BOOL CMultiCast::IsConnected() 
{ 
	return m_bConnected; 
} 
 
BOOL CMultiCast::CreateInstance(LPCTSTR strGroupAddr, unsigned short sPort, HWND hWnd) 
{ 
	if(m_bConnected == TRUE) 
	{ 
		TRACE("Has created successfully .\n"); 
		return TRUE; 
	} 
	 
	m_hWnd = hWnd; 
	m_sockRecv = socket(AF_INET, SOCK_DGRAM, 0); 
	if(m_sockRecv == INVALID_SOCKET) 
	{ 
		TRACE("ERRROR : socket - %d .\n", WSAGetLastError()); 
		return FALSE; 
	} 
 
	int optval = 1; 
	if(setsockopt(m_sockRecv, SOL_SOCKET,	SO_REUSEADDR,  
		(char *) & optval, sizeof(optval)) == SOCKET_ERROR) 
	{ 
		TRACE("ERRROR : setsockopt(SO_REUSEADDR) - %d .\n", WSAGetLastError()); 
		return FALSE; 
	} 
 
	m_saLocal.sin_addr.S_un.S_addr = htonl(INADDR_ANY); 
	m_saLocal.sin_family = AF_INET; 
	m_saLocal.sin_port = htons(sPort); 
	if(bind(m_sockRecv, (sockaddr *) & m_saLocal, sizeof(m_saLocal)) == SOCKET_ERROR) 
	{ 
		TRACE("ERRROR : bind(SO_REUSEADDR) - %d .\n", WSAGetLastError()); 
		return FALSE; 
	} 
 
	m_saGroup.sin_addr.S_un.S_addr = inet_addr(strGroupAddr); 
	m_saGroup.sin_family = AF_INET; 
	m_saGroup.sin_port = htons(sPort); 
 
	ip_mreq mcast; 
	mcast.imr_multiaddr.S_un.S_addr = m_saGroup.sin_addr.S_un.S_addr; 
	mcast.imr_interface.S_un.S_addr = m_saLocal.sin_addr.S_un.S_addr; 
	if (setsockopt(m_sockRecv, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
		(char *) & mcast, sizeof(mcast)) == SOCKET_ERROR) 
    { 
        TRACE("ERRROR : setsockopt(IP_ADD_MEMBERSHIP) - %d .\n", WSAGetLastError()); 
        return FALSE; 
    } 
 
	optval = 16; 
    if (setsockopt(m_sockRecv, IPPROTO_IP, IP_MULTICAST_TTL,  
        (char *) & optval, sizeof(optval)) == SOCKET_ERROR) 
    { 
        TRACE("ERRROR : setsockopt(IP_MULTICAST_TTL) - %d .\n", WSAGetLastError()); 
        return FALSE; 
    } 
 
	int ret = WSAAsyncSelect(m_sockRecv, m_hWnd, WM_MULTIPOINTEVENT,  
		FD_WRITE | FD_READ | FD_QOS | FD_GROUP_QOS | FD_CONNECT); 
	if(ret == SOCKET_ERROR) 
	{ 
        TRACE("ERRROR : WSAAsyncSelect - %d .\n", WSAGetLastError()); 
        return FALSE; 
	} 
	m_bConnected = TRUE; 
	return TRUE; 
} 
 
int CMultiCast::RecvData(char * pData, int nSize, sockaddr * pSA, int * pSALen) 
{ 
	if(m_bConnected == FALSE) 
	{ 
		TRACE("ERROR : RecvData - m_bConnected == FALSE .\n"); 
		return SOCKET_ERROR; 
	} 
 
	int ret; 
	if((ret = recvfrom(m_sockRecv, pData, nSize, 0, pSA, pSALen)) == SOCKET_ERROR) 
	{ 
        TRACE("ERROR : recvfrom - %d .\n", WSAGetLastError()); 
        return SOCKET_ERROR; 
	} 
 
	return ret; 
} 
 
int CMultiCast::SendData(const char * pData, int nSize) 
{ 
	if(m_bConnected == FALSE) 
	{ 
		TRACE("ERROR : SendData - m_bConnected == FALSE .\n"); 
		return SOCKET_ERROR; 
	} 
 
	int ret = sendto(m_sockRecv, pData, nSize, 0,  
		(sockaddr *) & m_saGroup, sizeof(m_saGroup)); 
	if(ret == SOCKET_ERROR) 
	{ 
		TRACE("ERROR : sendto -- %d .\n", WSAGetLastError()); 
		return SOCKET_ERROR; 
	} 
	return ret; 
} 
 
void CMultiCast::Close() 
{ 
	if(m_sockRecv != INVALID_SOCKET) 
	{ 
		///////////////////////////////´ÕºÏ×ÅÓà 
		ip_mreq mcast; 
		mcast.imr_multiaddr.S_un.S_addr = m_saGroup.sin_addr.S_un.S_addr; 
		mcast.imr_interface.S_un.S_addr = m_saLocal.sin_addr.S_un.S_addr; 
		if (setsockopt(m_sockRecv, IPPROTO_IP, IP_DROP_MEMBERSHIP, 
			(char *) & mcast, sizeof(mcast)) == SOCKET_ERROR) 
		{ 
			TRACE("ERRROR : setsockopt(IP_DROP_MEMBERSHIP) - %d .\n", WSAGetLastError()); 
		} 
		/////////////////////////////// 
		closesocket(m_sockRecv); 
	} 
	if(m_sockGroup != INVALID_SOCKET) 
		closesocket(m_sockGroup); 
 
	m_hWnd = NULL; 
	m_bConnected = FALSE; 
	m_sockRecv = INVALID_SOCKET; 
	m_sockGroup = INVALID_SOCKET; 
}