I implement a class SocketForMulticast inherit from CAsyncSocket. I use that class as fellow:SocketForMulticast socket; socket.SetPortAndAddr(strIP,nPort); socket.Create();在我们公司一直使用这个类,已经经过了很长一段时间的检验,其接收和发送都是正常的,代码如下: //File SocketForMulticast.cpp #include "stdafx.h" #include "SocketForMulticast.h"#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif///////////////////////////////////////////////////////////////////////////// // CSocketForMulticastCSocketForMulticast::CSocketForMulticast() {}CSocketForMulticast::~CSocketForMulticast() {} // Do not edit the following lines, which are needed by ClassWizard. #if 0 BEGIN_MESSAGE_MAP(CSocketForMulticast, CAsyncSocket) //{{AFX_MSG_MAP(CSocketForMulticast) //}}AFX_MSG_MAP END_MESSAGE_MAP() #endif // 0///////////////////////////////////////////////////////////////////////////// // CSocketForMulticast member functionsBOOL CSocketForMulticast::Create(UINT nSocketPort, int nSocketType, long lEvent, LPCTSTR lpszSocketAddress) { if (Socket(nSocketType, lEvent)) { int nRet; //nRet=::bind(m_hSocket,(struct sockaddr FAR *)&m_SrcAddr, // sizeof(struct sockaddr)); BOOL bRet= Bind((SOCKADDR* )&m_SrcAddr, sizeof(SOCKADDR));
// For remote port nRet=WSAHtons(m_hSocket,m_nSocketPort,&(m_DestAddr.sin_port)); // Join the multicase group SOCKET hSocket=WSAJoinLeaf(m_hSocket, (PSOCKADDR)&m_DestAddr,sizeof(m_DestAddr), NULL, NULL, NULL, NULL, JL_BOTH); return TRUE; } return FALSE; }BOOL CSocketForMulticast::Socket(int nSocketType, long lEvent, int nProtocolType, int nAddressFormat) { ASSERT(m_hSocket == INVALID_SOCKET);// m_hSocket = socket(nAddressFormat,nSocketType,nProtocolType); m_hSocket=WSASocket(nAddressFormat,nSocketType,0, (LPWSAPROTOCOL_INFO)NULL,0, WSA_FLAG_OVERLAPPED | WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF); if (m_hSocket != INVALID_SOCKET) { // Allow reuse of the local port number BOOL bFlag=TRUE; int nRet=::setsockopt(m_hSocket,SOL_SOCKET,SO_REUSEADDR, (char *)&bFlag,sizeof(bFlag)); // Set the IP TTL int nIP_TTL=2; DWORD cbRet; nRet=WSAIoctl(m_hSocket,SIO_MULTICAST_SCOPE, &nIP_TTL,sizeof(nIP_TTL), NULL, 0, &cbRet, NULL, NULL); // Disable loopback=FALSE bFlag=FALSE; nRet=WSAIoctl(m_hSocket,SIO_MULTIPOINT_LOOPBACK, &bFlag,sizeof(bFlag), NULL, 0, &cbRet, NULL, NULL); CAsyncSocket::AttachHandle(m_hSocket, this, FALSE); return AsyncSelect(lEvent); } return FALSE; }BOOL CSocketForMulticast::SetPortAndAddr(UINT nSocketPort,CString strSocketAddress) { m_nSocketPort =nSocketPort; m_strSocketAddress =strSocketAddress; // Convert address string to value for remote address int iLen=sizeof(SOCKADDR);
m_DestAddr.sin_family=PF_INET; int nRet=WSAStringToAddress( m_strSocketAddress.GetBuffer(m_strSocketAddress.GetLength()), AF_INET, NULL, (LPSOCKADDR)&m_DestAddr, &iLen); m_strSocketAddress.ReleaseBuffer(); if (nRet==SOCKET_ERROR ) return FALSE; // For local address m_SrcAddr.sin_family=PF_INET; m_SrcAddr.sin_port=::htons(m_nSocketPort); m_SrcAddr.sin_addr.s_addr=INADDR_ANY;
I use that class as fellow:SocketForMulticast socket;
socket.SetPortAndAddr(strIP,nPort);
socket.Create();在我们公司一直使用这个类,已经经过了很长一段时间的检验,其接收和发送都是正常的,代码如下:
//File SocketForMulticast.cpp
#include "stdafx.h"
#include "SocketForMulticast.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CSocketForMulticastCSocketForMulticast::CSocketForMulticast()
{}CSocketForMulticast::~CSocketForMulticast()
{}
// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CSocketForMulticast, CAsyncSocket)
//{{AFX_MSG_MAP(CSocketForMulticast)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0/////////////////////////////////////////////////////////////////////////////
// CSocketForMulticast member functionsBOOL CSocketForMulticast::Create(UINT nSocketPort, int nSocketType, long lEvent, LPCTSTR lpszSocketAddress)
{
if (Socket(nSocketType, lEvent))
{
int nRet; //nRet=::bind(m_hSocket,(struct sockaddr FAR *)&m_SrcAddr,
// sizeof(struct sockaddr));
BOOL bRet= Bind((SOCKADDR* )&m_SrcAddr, sizeof(SOCKADDR));
// For remote port
nRet=WSAHtons(m_hSocket,m_nSocketPort,&(m_DestAddr.sin_port)); // Join the multicase group
SOCKET hSocket=WSAJoinLeaf(m_hSocket,
(PSOCKADDR)&m_DestAddr,sizeof(m_DestAddr),
NULL,
NULL,
NULL,
NULL,
JL_BOTH); return TRUE;
}
return FALSE;
}BOOL CSocketForMulticast::Socket(int nSocketType, long lEvent, int nProtocolType, int nAddressFormat)
{
ASSERT(m_hSocket == INVALID_SOCKET);// m_hSocket = socket(nAddressFormat,nSocketType,nProtocolType);
m_hSocket=WSASocket(nAddressFormat,nSocketType,0,
(LPWSAPROTOCOL_INFO)NULL,0,
WSA_FLAG_OVERLAPPED |
WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF);
if (m_hSocket != INVALID_SOCKET)
{
// Allow reuse of the local port number
BOOL bFlag=TRUE;
int nRet=::setsockopt(m_hSocket,SOL_SOCKET,SO_REUSEADDR,
(char *)&bFlag,sizeof(bFlag)); // Set the IP TTL
int nIP_TTL=2;
DWORD cbRet;
nRet=WSAIoctl(m_hSocket,SIO_MULTICAST_SCOPE,
&nIP_TTL,sizeof(nIP_TTL),
NULL,
0,
&cbRet,
NULL,
NULL); // Disable loopback=FALSE
bFlag=FALSE;
nRet=WSAIoctl(m_hSocket,SIO_MULTIPOINT_LOOPBACK,
&bFlag,sizeof(bFlag),
NULL,
0,
&cbRet,
NULL,
NULL); CAsyncSocket::AttachHandle(m_hSocket, this, FALSE);
return AsyncSelect(lEvent);
}
return FALSE;
}BOOL CSocketForMulticast::SetPortAndAddr(UINT nSocketPort,CString strSocketAddress)
{
m_nSocketPort =nSocketPort;
m_strSocketAddress =strSocketAddress; // Convert address string to value for remote address
int iLen=sizeof(SOCKADDR);
m_DestAddr.sin_family=PF_INET;
int nRet=WSAStringToAddress(
m_strSocketAddress.GetBuffer(m_strSocketAddress.GetLength()),
AF_INET,
NULL,
(LPSOCKADDR)&m_DestAddr,
&iLen);
m_strSocketAddress.ReleaseBuffer(); if (nRet==SOCKET_ERROR )
return FALSE; // For local address
m_SrcAddr.sin_family=PF_INET;
m_SrcAddr.sin_port=::htons(m_nSocketPort);
m_SrcAddr.sin_addr.s_addr=INADDR_ANY;
return TRUE;
}BOOL CSocketForMulticast::SendData(const void* lpBuf,int nBufLen,LPDWORD lpNumberOfBytesSent)
{
int nRet; //nRet=SendTo(lpBuf, nBufLen, m_nSocketPort, (LPCTSTR) m_strSocketAddress); WSABUF stWSABuf; stWSABuf.buf=(char *)lpBuf;
stWSABuf.len=nBufLen; nRet=WSASendTo(m_hSocket,&stWSABuf,
1,
lpNumberOfBytesSent,
0,
(struct sockaddr *)&(m_DestAddr),
sizeof(struct sockaddr),
NULL,
NULL); if (nRet == SOCKET_ERROR )
return FALSE; return TRUE;}BOOL CSocketForMulticast::ReceiveData(void* lpBuf,int nBufLen,LPDWORD lpNumberOfBytesRecvd)
{
int nRet;
WSABUF stWSABuf; //nRet=ReceiveFrom( lpBuf,nBufLen, m_strSocketAddress, m_nSocketPort); if(lpBuf==NULL || lpNumberOfBytesRecvd==NULL)
return FALSE; stWSABuf.buf=(char *)lpBuf;
stWSABuf.len=nBufLen;
DWORD dFlag=0;
int iLen=sizeof(SOCKADDR);
nRet=WSARecvFrom(m_hSocket,&stWSABuf,
1,
lpNumberOfBytesRecvd,
&dFlag,
(struct sockaddr *)&m_SrcAddr,
&iLen,
NULL,
NULL);
if(nRet==SOCKET_ERROR )
return FALSE; return TRUE;
}
http://support.microsoft.com/default.aspx?scid=kb;en-us;214396