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