兄弟用多播实现通讯,开始时程序的收发都正常,可是运行了一段时间之后,套接字的发送功能仍正常,可以向该多播组内发送数据包,但其接收功能却不正常了,无法接收到任何数据,这是什么原因呢?请高手指教,多谢。
OS: Windows 2000 professional
开发语言: VC 6.0

解决方案 »

  1.   

    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;

    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;
    }
      

  2.   

    你需要先获取错误代码GetLastError(),再分析产生错误的原因。
      

  3.   

    可是并没有错误产生啊,只是正常情况下当有数据到达时,OnReceive()函数会被调用,但现在它没有被调用,而并不是调用某函数时出错。
      

  4.   

    这种错误我也碰到了,发送的那个socket仍然能发送,就是不能接收(接收时的错误为WSAECONNRESET,MSDN的解释是对方的端口无法到达),真是急死了,
      

  5.   

    这个例子说不定对你有所帮助,去看看吧:
    http://support.microsoft.com/default.aspx?scid=kb;en-us;214396