#if !defined(AFX_MULTICASTSOCKET_H__269E2C7F_2037_11D3_8EF3_0000C0FD25F8__INCLUDED_) #define AFX_MULTICASTSOCKET_H__269E2C7F_2037_11D3_8EF3_0000C0FD25F8__INCLUDED_#if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 // MulticastSocket.h : header file /////////////////////////////////////////////////////////////////////////////// // CMulticastSocket command target #define MAXCLIENT 64 /* MSG_SENID MSG_SENIP */ class CMulticastSocket : public CAsyncSocket { // Attributes public:// Operations public: CMulticastSocket(); virtual ~CMulticastSocket();// Overrides public: BOOL bDataReceived; BOOL SendTo(char * , char*, int); void SetLoopBack(BOOL); BOOL SetTTL(UINT nTTL); void SetServerID( int id ) ; BOOL StartServer() ; BOOL StartClient( char *serip ) ; BOOL EndServer(); BOOL EndClient(); // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMulticastSocket) public: virtual void OnReceive(int nErrorCode); //}}AFX_VIRTUAL // Generated message map functions //{{AFX_MSG(CMulticastSocket) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG// Implementation private: int GetClientListNO(); void GetHostName( char *hostip ) ; BOOL JoinGroup(CString, UINT, UINT, BOOL); BOOL LeaveGroup(); BOOL CreateSendingSocket(UINT, BOOL); BOOL CreateReceivingSocket(LPCTSTR, UINT);public: char m_strBuffer[3*1024]; // Receiving buffer for the packet that has arrived SOCKADDR_IN m_saHostGroup; // SOCKADDR structure to hold IP/Port of the Host group to send data to it ip_mreq m_mrMReq; // Contains IP and interface of the host group UINT m_nSendersPort; // Holds Port No. of the socket from which last packet was received CString m_strSendersIP; // Hold IP of the socket from which the last packet was received UINT m_nLocalPort; // Ephemeral port number of the sending port CString m_strLocalIP; // IP Address of the local host or your machine BOOL bForceNoLoopback; // If interface does not support lopback and the service is required, the bool is set to true CAsyncSocket m_SendSocket; // Socket for sending data to the host group BOOL bAsServer ; CString m_strClientList[MAXCLIENT] ; int ServerID ; char Serverip[20] ; char m_strBuf[4*1024] ; char m_strLocalip[16] ; BOOL bMsgRec ; // to test };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MULTICASTSOCKET_H__269E2C7F_2037_11D3_8EF3_0000C0FD25F8__INCLUDED_)
// MulticastSocket.cpp : implementation file //#include "stdafx.h" #include "CMulticastSocket.h" #include "MulticastSocket.h"#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif///////////////////////////////////////////////////////////////////////////// // CMulticastSocketCMulticastSocket::CMulticastSocket() { bForceNoLoopback = FALSE; bMsgRec = FALSE ; bDataReceived = FALSE; /* Variable defined for this project. Not necessarily part of CMulticastSocket */ bAsServer = FALSE ; for ( int i = 0 ; i < MAXCLIENT ; i++ ) { m_strClientList[i] = "0" ; } ServerID = -1 ; GetHostName( m_strLocalip ) ; }CMulticastSocket::~CMulticastSocket() { } // Do not edit the following lines, which are needed by ClassWizard. #if 0 BEGIN_MESSAGE_MAP(CMulticastSocket, CAsyncSocket) //{{AFX_MSG_MAP(CMulticastSocket) //}}AFX_MSG_MAP END_MESSAGE_MAP() #endif // 0///////////////////////////////////////////////////////////////////////////// // CMulticastSocket member functionsBOOL CMulticastSocket::CreateReceivingSocket(LPCTSTR strGroupIP, UINT nGroupPort) { /* Create socket for receiving packets from multicast group */ if(!Create(nGroupPort, SOCK_DGRAM, FD_READ)) { AfxMessageBox( "Create receive socket error " ) ; return FALSE; } BOOL bMultipleApps = TRUE; /* allow reuse of local port if needed */ SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET); /* Fill m_saHostGroup_in for sending datagrams */ memset(&m_saHostGroup, 0, sizeof(m_saHostGroup)); m_saHostGroup.sin_family = AF_INET; m_saHostGroup.sin_addr.s_addr = inet_addr(strGroupIP); m_saHostGroup.sin_port = htons((USHORT)nGroupPort); /* Join the multicast group */ m_mrMReq.imr_multiaddr.s_addr = inet_addr(strGroupIP); /* group addr */ m_mrMReq.imr_interface.s_addr = htons(INADDR_ANY); /* use default */ if(setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) == SOCKET_ERROR ) { AfxMessageBox( "set receive socket opt error" ) ; return FALSE; } return TRUE; }BOOL CMulticastSocket::CreateSendingSocket(UINT nTTL, BOOL bLoopBack) { if(!m_SendSocket.Create(0, SOCK_DGRAM, 0)) { // Create an unconnected UDP socket AfxMessageBox( "Create send socket error" ) ; return FALSE; } if(!SetTTL(nTTL)) // Set Time to Live as specified by user AfxMessageBox("Warning! Error Setting TTL"); SetLoopBack(bLoopBack); // Enable/Disable Loopback return TRUE; }BOOL CMulticastSocket::SetTTL(UINT nTTL) { /* Set Time to Live to parameter TTL */ if(m_SendSocket.SetSockOpt(IP_MULTICAST_TTL, &nTTL, sizeof(int), IPPROTO_IP) == 0) return FALSE; /* Error Setting TTL */ else return TRUE; /* else TTL set successfully */ }void CMulticastSocket::SetLoopBack(BOOL bLoop) { /* Set LOOPBACK option to TRUE OR FALSE according to IsLoop parameter */ int nLoopBack = (int)bLoop; if(m_SendSocket.SetSockOpt(IP_MULTICAST_LOOP, &nLoopBack, sizeof(int), IPPROTO_IP) == 0) { if(!bLoop) /* if required to stop loopback */ { bForceNoLoopback = TRUE; /* Internally making a note that loopback has to be disabled forcefilly */
// Get IP/Port for send socket in order to disable loopback forcefully */ char localHost[255] ; gethostname(localHost, 255) ; struct hostent *host = gethostbyname(localHost) ; /* Get local host IP */ m_strLocalIP = inet_ntoa (*(struct in_addr*)*host->h_addr_list) ; CString Dummy ; // Dummy string to be passed to the GetSockName function m_SendSocket.GetSockName(Dummy, m_nLocalPort) ; /* Get Port Number for Sending Port */ } } }
else if ( strcmp( m_strBuffer + 40 , "MSG_CLOIP" ) == 0 ) { for ( int i = 0 ; i < MAXCLIENT ; i++ ) { if ( m_strClientList[i] == m_strBuffer + 20 ) { m_strClientList[i] = "0" ; bDataReceived = FALSE ; bMsgRec = TRUE ; return ; } } } else if ( strcmp( m_strBuffer + 20 , "MSG_SNDID" ) == 0 ) { bDataReceived = FALSE ; return ; } else { if (!bForceNoLoopback || (bForceNoLoopback && !(m_strSendersIP == m_strLocalIP && m_nSendersPort == m_nLocalPort))) { // 1. If loopbackback is not to be forced then interface handles the loopback itself // 2. If you have to loopback and SOCKOPT LOOPBACK fails, no problem, interfaces loopback by default // 3. If you have to stop loopback and SOCKOPT LOOPBACK fails, ignore messages coming from your own sending socket
// TODO : Add your code for here. The packet received is in m_strBuffer bDataReceived = TRUE; /* Making note that a message has arrived */ } } } else { if ( strcmp( m_strBuffer + 40 , "MSG_SNDID" ) == 0 ) { if ( ServerID == -1 ) { ServerID = atoi( m_strBuffer + 55 ) ; } bDataReceived = FALSE ; return ; } else if ( strcmp( m_strBuffer + 20 , "MSG_SNDIP" ) == 0 ) { bDataReceived = FALSE ; return ; } else if ( strcmp( m_strBuffer + 20 , "MSG_CLOIP" ) == 0 ) { bDataReceived = FALSE ; return ; } else { if (!bForceNoLoopback || (bForceNoLoopback && !(m_strSendersIP == m_strLocalIP && m_nSendersPort == m_nLocalPort))) { // 1. If loopbackback is not to be forced then interface handles the loopback itself // 2. If you have to loopback and SOCKOPT LOOPBACK fails, no problem, interfaces loopback by default // 3. If you have to stop loopback and SOCKOPT LOOPBACK fails, ignore messages coming from your own sending socket
// TODO : Add your code for here. The packet received is in m_strBuffer bDataReceived = TRUE; /* Making note that a message has arrived */ } } } } CAsyncSocket::OnReceive(nErrorCode); }BOOL CMulticastSocket::LeaveGroup() { if(setsockopt (m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) < 0) return FALSE;
m_SendSocket.Close(); // Close sending socket Close(); // Close receving socket return TRUE; }BOOL CMulticastSocket::SendTo(char* ip , char* strMessage, int nSize) { char *str = new char[4*1024] ; memcpy( str , ip , 18 ) ; memcpy( str + 20 , m_strLocalip , 18 ) ; memcpy( str + 40 , strMessage , nSize ) ; if(m_SendSocket.SendTo( str , nSize + 40 , (SOCKADDR*)&m_saHostGroup, sizeof(SOCKADDR), 0) == SOCKET_ERROR) return FALSE; else return TRUE; }BOOL CMulticastSocket::JoinGroup(CString GroupIP, UINT nGroupPort, UINT nTTL, BOOL bLoopback) { if(!CreateReceivingSocket(GroupIP, nGroupPort)) /* Create Socket for receiving and join the host group */ return FALSE; if(!CreateSendingSocket(nTTL, bLoopback)) /* Create Socket for sending */ return FALSE; return TRUE; }BOOL CMulticastSocket::StartServer() { if(!JoinGroup( "228.5.6.7", (UINT)6789 , (UINT)10 , FALSE ) ) { AfxMessageBox("Error joining host group") ; return FALSE ; } unsigned long id = inet_addr ( m_strLocalip ) ; SetServerID( abs( id ) ) ; bAsServer = TRUE ; return TRUE ; }BOOL CMulticastSocket::StartClient( char *serip ) { if(!JoinGroup( "228.5.6.7", (UINT)6789 , (UINT)10 , FALSE ) ) { AfxMessageBox("Error joining host group") ; return FALSE ; } bAsServer = FALSE ; char ip[25] ; GetHostName( ip ) ; // AfxMessageBox( ip ) ; char strSend[200] ; strcpy( Serverip , serip ) ; memcpy( strSend , "MSG_SNDIP" , 12 ) ; //message type SendTo( Serverip , strSend , 255 ) ; return TRUE ; }void CMulticastSocket::GetHostName( char *hostip ) { char szHostname[256]; if ( gethostname( szHostname , sizeof( szHostname ) ) ) { TRACE( _T( "Failed in call to gethostname, WSAGetLastError returns %d\n" ) , WSAGetLastError() ) ; return ; } //get host information from the host name HOSTENT* pHostEnt = gethostbyname( szHostname ) ; if ( pHostEnt == NULL ) { TRACE( _T( "Failed in call to gethostbyname, WSAGetLastError returns %d\n" ) , WSAGetLastError( ) ) ; return ; } //check the length of the IP adress if ( pHostEnt->h_length != 4 ) { TRACE( _T( "IP address returned is not 32 bits !!\n" ) ) ; return ; } //call the virtual callback function in a loop int nAdapter = 0 ; unsigned long ip2 = *( unsigned long * )( pHostEnt->h_addr_list[nAdapter] ) ; in_addr tmp ; tmp = *( in_addr * )&ip2 ; strcpy( hostip , inet_ntoa( tmp ) ) ; }void CMulticastSocket::SetServerID( int id ) { ServerID = id ; }int CMulticastSocket::GetClientListNO() { for ( int i = 0 ; i < MAXCLIENT ; i++ ) { if ( m_strClientList[i] == "0" ) { return i ; } } return -1 ; }BOOL CMulticastSocket::EndClient() { if(setsockopt (m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) < 0) { return FALSE; } char strSnd[255] ; strcpy( strSnd , "MSG_CLOIP" ) ; char ip[25] ; GetHostName( ip ) ; SendTo( Serverip , strSnd , 255 ) ; m_SendSocket.Close(); // Close sending socket Close(); // Close receving socket ServerID = -1 ; return TRUE; }BOOL CMulticastSocket::EndServer() { if(setsockopt (m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) < 0) { return FALSE; } m_SendSocket.Close(); // Close sending socket Close(); // Close receving socket return TRUE;}
#define AFX_MULTICASTSOCKET_H__269E2C7F_2037_11D3_8EF3_0000C0FD25F8__INCLUDED_#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// MulticastSocket.h : header file
///////////////////////////////////////////////////////////////////////////////
// CMulticastSocket command target
#define MAXCLIENT 64
/*
MSG_SENID
MSG_SENIP
*/
class CMulticastSocket : public CAsyncSocket
{
// Attributes
public:// Operations
public:
CMulticastSocket();
virtual ~CMulticastSocket();// Overrides
public:
BOOL bDataReceived;
BOOL SendTo(char * , char*, int);
void SetLoopBack(BOOL);
BOOL SetTTL(UINT nTTL);
void SetServerID( int id ) ;
BOOL StartServer() ;
BOOL StartClient( char *serip ) ;
BOOL EndServer();
BOOL EndClient();
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMulticastSocket)
public:
virtual void OnReceive(int nErrorCode);
//}}AFX_VIRTUAL // Generated message map functions
//{{AFX_MSG(CMulticastSocket)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG// Implementation
private:
int GetClientListNO();
void GetHostName( char *hostip ) ;
BOOL JoinGroup(CString, UINT, UINT, BOOL);
BOOL LeaveGroup();
BOOL CreateSendingSocket(UINT, BOOL);
BOOL CreateReceivingSocket(LPCTSTR, UINT);public:
char m_strBuffer[3*1024]; // Receiving buffer for the packet that has arrived
SOCKADDR_IN m_saHostGroup; // SOCKADDR structure to hold IP/Port of the Host group to send data to it
ip_mreq m_mrMReq; // Contains IP and interface of the host group
UINT m_nSendersPort; // Holds Port No. of the socket from which last packet was received
CString m_strSendersIP; // Hold IP of the socket from which the last packet was received
UINT m_nLocalPort; // Ephemeral port number of the sending port
CString m_strLocalIP; // IP Address of the local host or your machine
BOOL bForceNoLoopback; // If interface does not support lopback and the service is required, the bool is set to true
CAsyncSocket m_SendSocket; // Socket for sending data to the host group
BOOL bAsServer ;
CString m_strClientList[MAXCLIENT] ;
int ServerID ;
char Serverip[20] ;
char m_strBuf[4*1024] ;
char m_strLocalip[16] ;
BOOL bMsgRec ; // to test
};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.#endif // !defined(AFX_MULTICASTSOCKET_H__269E2C7F_2037_11D3_8EF3_0000C0FD25F8__INCLUDED_)
//#include "stdafx.h"
#include "CMulticastSocket.h"
#include "MulticastSocket.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMulticastSocketCMulticastSocket::CMulticastSocket()
{
bForceNoLoopback = FALSE;
bMsgRec = FALSE ;
bDataReceived = FALSE; /* Variable defined for this project. Not necessarily part of CMulticastSocket */
bAsServer = FALSE ;
for ( int i = 0 ; i < MAXCLIENT ; i++ )
{
m_strClientList[i] = "0" ;
}
ServerID = -1 ;
GetHostName( m_strLocalip ) ;
}CMulticastSocket::~CMulticastSocket()
{
}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CMulticastSocket, CAsyncSocket)
//{{AFX_MSG_MAP(CMulticastSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0/////////////////////////////////////////////////////////////////////////////
// CMulticastSocket member functionsBOOL CMulticastSocket::CreateReceivingSocket(LPCTSTR strGroupIP, UINT nGroupPort)
{
/* Create socket for receiving packets from multicast group */
if(!Create(nGroupPort, SOCK_DGRAM, FD_READ))
{
AfxMessageBox( "Create receive socket error " ) ;
return FALSE;
}
BOOL bMultipleApps = TRUE; /* allow reuse of local port if needed */
SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET); /* Fill m_saHostGroup_in for sending datagrams */
memset(&m_saHostGroup, 0, sizeof(m_saHostGroup)); m_saHostGroup.sin_family = AF_INET;
m_saHostGroup.sin_addr.s_addr = inet_addr(strGroupIP);
m_saHostGroup.sin_port = htons((USHORT)nGroupPort); /* Join the multicast group */
m_mrMReq.imr_multiaddr.s_addr = inet_addr(strGroupIP); /* group addr */
m_mrMReq.imr_interface.s_addr = htons(INADDR_ANY); /* use default */ if(setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) == SOCKET_ERROR )
{
AfxMessageBox( "set receive socket opt error" ) ;
return FALSE;
} return TRUE;
}BOOL CMulticastSocket::CreateSendingSocket(UINT nTTL, BOOL bLoopBack)
{
if(!m_SendSocket.Create(0, SOCK_DGRAM, 0))
{
// Create an unconnected UDP socket
AfxMessageBox( "Create send socket error" ) ;
return FALSE;
} if(!SetTTL(nTTL)) // Set Time to Live as specified by user
AfxMessageBox("Warning! Error Setting TTL"); SetLoopBack(bLoopBack); // Enable/Disable Loopback return TRUE;
}BOOL CMulticastSocket::SetTTL(UINT nTTL)
{
/* Set Time to Live to parameter TTL */
if(m_SendSocket.SetSockOpt(IP_MULTICAST_TTL, &nTTL, sizeof(int), IPPROTO_IP) == 0)
return FALSE; /* Error Setting TTL */
else
return TRUE; /* else TTL set successfully */
}void CMulticastSocket::SetLoopBack(BOOL bLoop)
{
/* Set LOOPBACK option to TRUE OR FALSE according to IsLoop parameter */
int nLoopBack = (int)bLoop;
if(m_SendSocket.SetSockOpt(IP_MULTICAST_LOOP, &nLoopBack, sizeof(int), IPPROTO_IP) == 0)
{
if(!bLoop) /* if required to stop loopback */
{
bForceNoLoopback = TRUE; /* Internally making a note that loopback has to be disabled forcefilly */
// Get IP/Port for send socket in order to disable loopback forcefully */
char localHost[255] ;
gethostname(localHost, 255) ;
struct hostent *host = gethostbyname(localHost) ; /* Get local host IP */
m_strLocalIP = inet_ntoa (*(struct in_addr*)*host->h_addr_list) ;
CString Dummy ; // Dummy string to be passed to the GetSockName function
m_SendSocket.GetSockName(Dummy, m_nLocalPort) ; /* Get Port Number for Sending Port */
}
}
}
void CMulticastSocket::OnReceive(int nErrorCode)
{
int nError = ReceiveFrom (m_strBuffer, 32000, m_strSendersIP, m_nSendersPort);
memcpy( m_strBuf , m_strBuffer + 40 , 1024 * 4 ) ;
if(nError == SOCKET_ERROR)
{
AfxMessageBox("Error receiving data from the host group");
return ;
}
if ( strcmp( m_strLocalip , m_strBuffer ) == 0 )
{
if ( bAsServer )
{
if ( strcmp( m_strBuffer + 40 , "MSG_SNDIP" ) == 0 )
{
int id = GetClientListNO() ;
m_strClientList[id] = m_strBuffer + 20 ;
char strSnd[255] ;
char iid[16] ;
sprintf( iid , "%d" , ServerID ) ;
// strcpy( strSnd , m_strBuffer + 35 ) ;
strcpy( strSnd , "MSG_SNDID" ) ;
strcpy( strSnd + 15 , iid ) ;
bMsgRec = TRUE ;
SendTo( m_strBuffer + 20 , strSnd , 255 ) ;
bDataReceived = FALSE ;
return ;
}
else if ( strcmp( m_strBuffer + 40 , "MSG_CLOIP" ) == 0 )
{
for ( int i = 0 ; i < MAXCLIENT ; i++ )
{
if ( m_strClientList[i] == m_strBuffer + 20 )
{
m_strClientList[i] = "0" ;
bDataReceived = FALSE ;
bMsgRec = TRUE ;
return ;
}
}
}
else if ( strcmp( m_strBuffer + 20 , "MSG_SNDID" ) == 0 )
{
bDataReceived = FALSE ;
return ;
}
else
{
if (!bForceNoLoopback || (bForceNoLoopback && !(m_strSendersIP == m_strLocalIP && m_nSendersPort == m_nLocalPort)))
{
// 1. If loopbackback is not to be forced then interface handles the loopback itself
// 2. If you have to loopback and SOCKOPT LOOPBACK fails, no problem, interfaces loopback by default
// 3. If you have to stop loopback and SOCKOPT LOOPBACK fails, ignore messages coming from your own sending socket
// TODO : Add your code for here. The packet received is in m_strBuffer
bDataReceived = TRUE; /* Making note that a message has arrived */
}
}
}
else
{
if ( strcmp( m_strBuffer + 40 , "MSG_SNDID" ) == 0 )
{
if ( ServerID == -1 )
{
ServerID = atoi( m_strBuffer + 55 ) ;
}
bDataReceived = FALSE ;
return ;
}
else if ( strcmp( m_strBuffer + 20 , "MSG_SNDIP" ) == 0 )
{
bDataReceived = FALSE ;
return ;
}
else if ( strcmp( m_strBuffer + 20 , "MSG_CLOIP" ) == 0 )
{
bDataReceived = FALSE ;
return ;
}
else
{
if (!bForceNoLoopback || (bForceNoLoopback && !(m_strSendersIP == m_strLocalIP && m_nSendersPort == m_nLocalPort)))
{
// 1. If loopbackback is not to be forced then interface handles the loopback itself
// 2. If you have to loopback and SOCKOPT LOOPBACK fails, no problem, interfaces loopback by default
// 3. If you have to stop loopback and SOCKOPT LOOPBACK fails, ignore messages coming from your own sending socket
// TODO : Add your code for here. The packet received is in m_strBuffer
bDataReceived = TRUE; /* Making note that a message has arrived */
}
}
}
}
CAsyncSocket::OnReceive(nErrorCode);
}BOOL CMulticastSocket::LeaveGroup()
{
if(setsockopt (m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) < 0)
return FALSE;
m_SendSocket.Close(); // Close sending socket
Close(); // Close receving socket
return TRUE;
}BOOL CMulticastSocket::SendTo(char* ip , char* strMessage, int nSize)
{
char *str = new char[4*1024] ;
memcpy( str , ip , 18 ) ;
memcpy( str + 20 , m_strLocalip , 18 ) ;
memcpy( str + 40 , strMessage , nSize ) ;
if(m_SendSocket.SendTo( str , nSize + 40 , (SOCKADDR*)&m_saHostGroup, sizeof(SOCKADDR), 0) == SOCKET_ERROR)
return FALSE;
else
return TRUE;
}BOOL CMulticastSocket::JoinGroup(CString GroupIP, UINT nGroupPort, UINT nTTL, BOOL bLoopback)
{
if(!CreateReceivingSocket(GroupIP, nGroupPort)) /* Create Socket for receiving and join the host group */
return FALSE;
if(!CreateSendingSocket(nTTL, bLoopback)) /* Create Socket for sending */
return FALSE;
return TRUE;
}BOOL CMulticastSocket::StartServer()
{
if(!JoinGroup( "228.5.6.7", (UINT)6789 , (UINT)10 , FALSE ) )
{
AfxMessageBox("Error joining host group") ;
return FALSE ;
}
unsigned long id = inet_addr ( m_strLocalip ) ;
SetServerID( abs( id ) ) ;
bAsServer = TRUE ;
return TRUE ;
}BOOL CMulticastSocket::StartClient( char *serip )
{
if(!JoinGroup( "228.5.6.7", (UINT)6789 , (UINT)10 , FALSE ) )
{
AfxMessageBox("Error joining host group") ;
return FALSE ;
}
bAsServer = FALSE ;
char ip[25] ;
GetHostName( ip ) ;
// AfxMessageBox( ip ) ;
char strSend[200] ;
strcpy( Serverip , serip ) ; memcpy( strSend , "MSG_SNDIP" , 12 ) ; //message type
SendTo( Serverip , strSend , 255 ) ;
return TRUE ;
}void CMulticastSocket::GetHostName( char *hostip )
{
char szHostname[256];
if ( gethostname( szHostname , sizeof( szHostname ) ) )
{
TRACE( _T( "Failed in call to gethostname, WSAGetLastError returns %d\n" ) , WSAGetLastError() ) ;
return ;
} //get host information from the host name
HOSTENT* pHostEnt = gethostbyname( szHostname ) ;
if ( pHostEnt == NULL )
{
TRACE( _T( "Failed in call to gethostbyname, WSAGetLastError returns %d\n" ) , WSAGetLastError( ) ) ;
return ;
} //check the length of the IP adress
if ( pHostEnt->h_length != 4 )
{
TRACE( _T( "IP address returned is not 32 bits !!\n" ) ) ;
return ;
} //call the virtual callback function in a loop
int nAdapter = 0 ;
unsigned long ip2 = *( unsigned long * )( pHostEnt->h_addr_list[nAdapter] ) ;
in_addr tmp ;
tmp = *( in_addr * )&ip2 ;
strcpy( hostip , inet_ntoa( tmp ) ) ;
}void CMulticastSocket::SetServerID( int id )
{
ServerID = id ;
}int CMulticastSocket::GetClientListNO()
{
for ( int i = 0 ; i < MAXCLIENT ; i++ )
{
if ( m_strClientList[i] == "0" )
{
return i ;
}
}
return -1 ;
}BOOL CMulticastSocket::EndClient()
{
if(setsockopt (m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) < 0)
{
return FALSE;
}
char strSnd[255] ;
strcpy( strSnd , "MSG_CLOIP" ) ;
char ip[25] ;
GetHostName( ip ) ;
SendTo( Serverip , strSnd , 255 ) ;
m_SendSocket.Close(); // Close sending socket
Close(); // Close receving socket
ServerID = -1 ;
return TRUE;
}BOOL CMulticastSocket::EndServer()
{
if(setsockopt (m_hSocket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq)) < 0)
{
return FALSE;
}
m_SendSocket.Close(); // Close sending socket
Close(); // Close receving socket
return TRUE;}