加入组播时失败,错误返回10049
同样的程序,一台机子成功,另一台机子失败
代码如下:
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = htonl(mMulticastIP);
mreq.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt(mSckReceiver, IPPROTO_IP, IP_ADD_MEMBERSHIP,(char *)&mreq, sizeof(mreq));
其中在一台机子上ret的值为0,另一台机子ret的值为-1
困惑中,在线等
[解决办法]
我现在使用的一个组播类,
.h文件的内容:
#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//#define BUF_SIZE 1024class CMulticastSocket : public CObject {public: CMulticastSocket(); virtual ~CMulticastSocket();public: static BOOL InitInstance(); static BOOL UninInstance();public: BOOL IsConnected(); BOOL CreateInstance(const char* strGroupAddr, unsigned short sPort, HWND hWnd); int RecvData(char * pData, int nSize, sockaddr * pSA = NULL, int * pSALen = NULL); int SendData(const char * pData, int nSize); void Close();public: HWND m_hWnd; SOCKET m_sockGroup; SOCKET m_sockRecv; BOOL m_bConnected; sockaddr_in m_saGroup; sockaddr_in m_saLocal;};///////////////////////////////////////////////////////////////////////////////{{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_)
[解决办法]
.cpp的内容:
// MulticastSocket.cpp : implementation file//#include "stdafx.h"#include "MulticastSocket.h"#include "HuanRemoteServiceDlg.h"#include "atlconv.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCMulticastSocket::CMulticastSocket(){ m_hWnd = NULL; m_bConnected = FALSE; m_sockRecv = INVALID_SOCKET; m_sockGroup = INVALID_SOCKET;}CMulticastSocket::~CMulticastSocket(){}BOOL CMulticastSocket::InitInstance(){ WSADATA wsadata; if(WSAStartup(0x0202, & wsadata) != 0) { TRACE("ERROR : InitInstance !\n"); return FALSE; } return TRUE;}BOOL CMulticastSocket::UninInstance(){ if(WSACleanup() != 0) { TRACE("ERROR : UninInstance - %d .\n", WSAGetLastError()); return FALSE; } return TRUE;}BOOL CMulticastSocket::IsConnected(){ return m_bConnected;}BOOL CMulticastSocket::CreateInstance(const char* strGroupAddr, unsigned short sPort, HWND hWnd){ if(m_bConnected == TRUE) { TRACE("Has created successfully .\n"); return TRUE; } m_hWnd = hWnd; m_sockRecv = socket(AF_INET, SOCK_DGRAM, 0); if(m_sockRecv == INVALID_SOCKET) { TRACE("ERRROR : socket - %d .\n", WSAGetLastError()); return FALSE; } int optval = 1; if(setsockopt(m_sockRecv, SOL_SOCKET, SO_REUSEADDR, (char *) & optval, sizeof(optval)) == SOCKET_ERROR) { TRACE("ERRROR : setsockopt(SO_REUSEADDR) - %d .\n", WSAGetLastError()); return FALSE; } m_saLocal.sin_addr.S_un.S_addr = htonl(INADDR_ANY); m_saLocal.sin_family = AF_INET; m_saLocal.sin_port = htons(sPort); if(bind(m_sockRecv, (sockaddr *) & m_saLocal, sizeof(m_saLocal)) == SOCKET_ERROR) { TRACE("ERRROR : bind(SO_REUSEADDR) - %d .\n", WSAGetLastError()); return FALSE; } m_saGroup.sin_addr.S_un.S_addr = inet_addr(strGroupAddr); m_saGroup.sin_family = AF_INET; m_saGroup.sin_port = htons(sPort); ip_mreq mcast; mcast.imr_multiaddr.S_un.S_addr = m_saGroup.sin_addr.S_un.S_addr; mcast.imr_interface.S_un.S_addr = m_saLocal.sin_addr.S_un.S_addr; if (setsockopt(m_sockRecv, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) & mcast, sizeof(mcast)) == SOCKET_ERROR) { TRACE("ERRROR : setsockopt(IP_ADD_MEMBERSHIP) - %d .\n", WSAGetLastError()); return FALSE; } //optval = 16; optval = 1; if (setsockopt(m_sockRecv, IPPROTO_IP, IP_MULTICAST_TTL, (char *) & optval, sizeof(optval)) == SOCKET_ERROR) { TRACE("ERRROR : setsockopt(IP_MULTICAST_TTL) - %d .\n", WSAGetLastError()); return FALSE; } int ret = WSAAsyncSelect(m_sockRecv, m_hWnd, WM_MULTIPOINTEVENT, FD_WRITE | FD_READ | FD_QOS | FD_GROUP_QOS | FD_CONNECT); if(ret == SOCKET_ERROR) { TRACE("ERRROR : WSAAsyncSelect - %d .\n", WSAGetLastError()); return FALSE; } m_bConnected = TRUE; return TRUE;}int CMulticastSocket::RecvData(char * pData, int nSize, sockaddr * pSA, int * pSALen){ if(m_bConnected == FALSE) { TRACE("ERROR : RecvData - m_bConnected == FALSE .\n"); return SOCKET_ERROR; } int ret; if((ret = recvfrom(m_sockRecv, pData, nSize, 0, pSA, pSALen)) == SOCKET_ERROR) { TRACE("ERROR : recvfrom - %d .\n", WSAGetLastError()); return SOCKET_ERROR; } return ret;}int CMulticastSocket::SendData(const char * pData, int nSize){ if(m_bConnected == FALSE) { TRACE("ERROR : SendData - m_bConnected == FALSE .\n"); return SOCKET_ERROR; } int ret = sendto(m_sockRecv, pData, nSize, 0, (sockaddr *) & m_saGroup, sizeof(m_saGroup)); if(ret == SOCKET_ERROR) { TRACE("ERROR : sendto -- %d .\n", WSAGetLastError()); return SOCKET_ERROR; } return ret;}void CMulticastSocket::Close(){ if(m_sockRecv != INVALID_SOCKET) { ///////////////////////////////凑合着用 ip_mreq mcast; mcast.imr_multiaddr.S_un.S_addr = m_saGroup.sin_addr.S_un.S_addr; mcast.imr_interface.S_un.S_addr = m_saLocal.sin_addr.S_un.S_addr; if (setsockopt(m_sockRecv, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&mcast, sizeof(mcast)) == SOCKET_ERROR) { TRACE("ERRROR : setsockopt(IP_DROP_MEMBERSHIP) - %d .\n", WSAGetLastError()); } /////////////////////////////// closesocket(m_sockRecv); } if(m_sockGroup != INVALID_SOCKET) { closesocket(m_sockGroup); } m_hWnd = NULL; m_bConnected = FALSE; m_sockRecv = INVALID_SOCKET; m_sockGroup = INVALID_SOCKET;}
[解决办法]
另外在上层增加对接收消息的处理:
afx_msg LRESULT OnReceive(WPARAM wParam, LPARAM lParam);ON_MESSAGE(WM_MULTIPOINTEVENT, OnReceive)// 功能描述:接收到多播数据后的回调函数LRESULT CHuanRemoteServiceDlg::OnReceive(WPARAM wParam, LPARAM lParam){ SOCKET sockfd = (SOCKET)wParam; if(WSAGETSELECTERROR(lParam) != 0) { TRACE("ERROR : Recv - %d .\n", WSAGetLastError()); m_nMultSocket.Close(); return 0; } sockaddr_in from; int ret, salen = sizeof(from); char buff[BUF_SIZE + 1]; CString strMsg; switch(WSAGETSELECTEVENT(lParam)) { case FD_WRITE: TRACE("Now can sending data now!\n"); break; case FD_READ: ret = m_nMultSocket.RecvData(buff, BUF_SIZE, (sockaddr *) & from, & salen); if(ret == SOCKET_ERROR) { m_nMultSocket.Close(); } else if(ret != 0) { buff[ret] = '\0'; strMsg = (CString)buff; } break; case FD_QOS: break; case FD_GROUP_QOS: break; default: break; } return 0;}
[解决办法]