Multicast.cpp
上传用户:popouu88
上传日期:2013-02-11
资源大小:2894k
文件大小:3k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. // Multicast.cpp: implementation of the CMulticast class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "..stdafx.h"
  5. #include "Multicast.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. #pragma comment( lib , "ws2_32.lib")
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. int CMulticast::InitWSAStatup = 0;
  16. CMulticast::CMulticast()
  17. {
  18. if( ! CMulticast::InitWSAStatup )
  19. {
  20. WSADATA data;
  21. ::WSAStartup( MAKEWORD( 2 , 2 ) , &data );
  22. }
  23. CMulticast::InitWSAStatup ++;
  24. this->m_sock = INVALID_SOCKET;
  25. memset( &this->addr , 0 , sizeof( this->addr ) );
  26. memset( &this->command , 0 , sizeof( this->command ) );
  27. this->user_data = 0;
  28. memset( &this->recvBuffer , 0 , sizeof( this->recvBuffer ) );
  29. }
  30. CMulticast::~CMulticast()
  31. {
  32. CMulticast::InitWSAStatup -- ;
  33. if( ! CMulticast::InitWSAStatup )
  34. ::WSACleanup( );
  35. }
  36. //加入组播
  37. bool CMulticast::AddMemberShip( const char * ip , const int port )
  38. {
  39. this->DropMemberShip( );
  40. if( ( this->m_sock = ::socket( AF_INET , SOCK_DGRAM ,  0 ) ) == INVALID_SOCKET )
  41. return false;
  42. this->addr.sin_family = AF_INET;
  43. this->addr.sin_addr.s_addr = INADDR_ANY;
  44. this->addr.sin_port = ::htons( port );
  45. int on = 1;
  46.     //设定端口可重用
  47.     if( ::setsockopt( this->m_sock , SOL_SOCKET , SO_REUSEADDR , ( const char * )&on , sizeof( on ) ) < 0 )
  48. {
  49. this->DropMemberShip( );
  50. return false;
  51. }//绑定端口
  52. if( ::bind( this->m_sock , ( struct sockaddr * )&this->addr , sizeof( this->addr ) ) == SOCKET_ERROR )
  53. {
  54. this->DropMemberShip( );
  55. return false;
  56. }
  57. this->command.imr_multiaddr.s_addr = inet_addr( ip ); 
  58.     this->command.imr_interface.s_addr = INADDR_ANY;
  59. if( this->command.imr_multiaddr.s_addr == -1 ) 
  60. {
  61. this->DropMemberShip( );
  62. return false;
  63. }//加入组播
  64. if( ::setsockopt( this->m_sock , IPPROTO_IP , IP_ADD_MEMBERSHIP , ( const char * )&this->command , sizeof( this->command ) ) < 0 )
  65. {
  66. this->DropMemberShip( );
  67. return false;
  68. }//保存组播地址
  69. this->addr.sin_addr.s_addr = ::inet_addr( ip );
  70. return true;
  71. }
  72. //从组播中移出
  73. void CMulticast::DropMemberShip( void )
  74. {
  75. if( this->IsConnected( ) )
  76. {   //移出租播
  77. ::setsockopt( this->m_sock , IPPROTO_IP , IP_DROP_MEMBERSHIP , ( const char * )&this->command , sizeof( this->command ) );
  78. ::closesocket( this->m_sock );
  79. this->m_sock = INVALID_SOCKET;
  80. }
  81. memset( &this->command , 0 , sizeof( this->command ) );
  82. }
  83. //发送组播数据
  84. bool CMulticast::SendTo( CBuffer & buffer )
  85. {
  86. if( this->IsConnected( ) )
  87. return ::sendto( this->m_sock , buffer.GetBuffer( ) , *( int * )buffer.GetBuffer( ) , 0 , ( struct sockaddr * )&this->addr , sizeof( this->addr ) );
  88. return false;
  89. }
  90. //接收组播数据
  91. bool CMulticast::ReceiveFrom( CBuffer & buffer )
  92. {
  93. if( ! this->IsConnected( ) )
  94. return false;
  95. struct sockaddr_in addr;
  96. int len = sizeof( addr );
  97. if( ::recvfrom( this->m_sock , this->recvBuffer , MAX_BUFFER_SIZE , 0 , ( struct sockaddr * )&addr , &len ) >= *( int * )this->recvBuffer )
  98. {
  99. if( buffer.GetSize( ) < *( int * )this->recvBuffer )
  100. buffer.Resize( *( int * )this->recvBuffer );
  101. memcpy( buffer.GetBuffer( ) , this->recvBuffer , *( int * )this->recvBuffer );
  102. return true;
  103. }
  104. return false;
  105. }