首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > VC >

急CAsyncSocket SetSockOpt 自发自收有关问题 ?

2012-12-16 
急:CAsyncSocket SetSockOpt 自发自收问题 ??CAsyncSocket SetSockOpt IP_MULTICAST_LOOP问题想实现UDP组

急:CAsyncSocket SetSockOpt 自发自收问题 ??
CAsyncSocket SetSockOpt IP_MULTICAST_LOOP  问题
想实现UDP组播,从网上下了个类,class CMulticastSocket : public CAsyncSocket

基本实现了发送和接受,可是遇见了问题:不能实现发送不让自己收到,无论nLoopBack 0 和1,设置返回都是1,为错误。

SetSockOpt(IP_MULTICAST_LOOP, &nLoopBack, sizeof(int), IPPROTO_IP)


具体代码如下:请大家分析分析::


CMulticastSocket::CMulticastSocket()
{
bForceNoLoopback = FALSE;
bDataReceived = TRUE;/* Variable defined for this project. Not necessarily part of CMulticastSocket */
}

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 functions

BOOL CMulticastSocket::CreateReceivingSocket(LPCTSTR strGroupIP, UINT nGroupPort)
{
/* Create socket for receiving packets from multicast group */
if(!Create(nGroupPort, SOCK_DGRAM, FD_READ))
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)) < 0)
return FALSE;

return TRUE;
}

BOOL CMulticastSocket::CreateSendingSocket(UINT nTTL, BOOL bLoopBack)
{
if(!m_SendSocket.Create(0, SOCK_DGRAM, 0))// Create an unconnected UDP socket
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;
int i = m_SendSocket.SetSockOpt(IP_MULTICAST_LOOP, &nLoopBack, sizeof(int), IPPROTO_IP);


if(i == 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);
if(nError == SOCKET_ERROR)
AfxMessageBox("Error receiving data from the host group");
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(const void* strMessage, int nSize)
{
if(m_SendSocket.SendTo(strMessage, nSize, (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;


[最优解释]
你把这行

int i = m_SendSocket.SetSockOpt(IP_MULTICAST_LOOP, &nLoopBack, sizeof(int), IPPROTO_IP);



改成 int i = setsockopt(m_SendSocket,IPPROTO_IP,IP_MULTICAST_LOOP,(char*)&nLoopBack, sizeof(int));

就可以了。

热点排行