📄 cmulticastadmin.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 + -