求助各位神:
  我写了一个程序,具体就是每个用户在创建套接字后加入一个多播组,问题在于比如说有A,B两个主机,A先加入多播组,B后加入同一个多播组,但是若B先发送信息至多播组,A接收不到,A发送信息至多播组,B能收到。而且在B 接收到A的信息后,就能正常发送信息到多播组了。通过断点,监视,发现发送信息并没有任何问题。难道是哪里的逻辑错误??
  大致说一下我的代码
  在Dlg类里面我设置了一个响应加入按钮的函数
  CMulticastDLG::OnBnClickedJoin()
{
  m_sock.create(...);//自己定义的类,封装了create函数,create用于创建套接字,绑定,并且通过WSAJoinLeaf()函数加入一个组,然后设置了io模型,定义了一个自己注册的网络事件
 m_noti.format("..")
 m_sock.send(...)//上线通知
}//以下是我自定义的CMulticast类的create函数CMulticast::create()
{
  m_socket=wsasocket(..);//设置为重叠io,以及创建了控制层面的叶节点,数据层面的叶节点
  地址初始化包括协议族,端口和IP,IP设置为网络字节顺序的0.0.0.0;
  设置可重用地址;
  bind(m_socket);
  设定本地回环及TTL;
  然后初始化目标地址(组播地址)结构体m_srcadd;
  m_groupsock=wsajoinleaf(m_socket,...);
  //最后是SELECT函数
  wsaasyncselect(m_groupsock,...,MULTICASTEVENT,..)//MULTICASTEVENT是我自定义的事件 MULTICASTEVENT=WM_USER+1001
}
 
 CMulticast::Send()
{
  wsasendto(m_sock,..);
}CMulticast::rev(){
  wsarecvfrom(m_groupsocket,...);
}最后是我在DLG类声明定义了一个消息映射,目的是用ONReceive函数响应前文说的MULTICASTEVENT事件。
LONG CMultiCast_PCDlg::OnReceive(WPARAM wParam, LPARAM lParam)
{
   .....
switch(WSAGETSELECTEVENT(lParam))
{
case FD_WRITE:
TRACE("Now can sending data now!\n");
break;

        case FD_READ:  Receive();
break;

       case FD_QOS:
break;
case FD_GROUP_QOS:
break;
default:
break;
}
return 0L;
}

解决方案 »

  1.   

    多播有三个级别:0, 1, 2. 其中0,不能发送也不能接收;级别1,只能发送不能接收,主机不需要加入多播组;级别2,能发送也能接收,主机需要加入多播组.从你的描述看,处于级别2,原则上讲,只要主机加入了多播组,它发送的数据就能够被其它的主机接收到,况且你的主机A是先加入的.你可以看一下发送出去的包是否端口或地址不对.
    关于多播编程你可以参考《WinSock网络编程经络》第22章,下面的源码解压后找SNTP,是用多播实现的,仅供参考,下载地址:http://download.csdn.net/detail/geoff08zhang/4571358
      

  2.   


    我将发送套接字m_sock与m_addr绑定,在绑定之前我初始化m_addr结构如下
            m_Addr.sin_family= PF_INET;
    m_Addr.sin_port = htons (port);
    m_Addr.sin_addr.s_addr =htonl(INADDR_ANY) ;
    然后就这个m_addr结构就没修改过在加入组之前我初始化目标地址结构m_srcaddr,代码如下;
    m_SrcAddr.sin_family=AF_INET;
    m_SrcAddr.sin_port = htons (port);
    m_SrcAddr.sin_addr.s_addr=inet_addr(lpstrAddr.GetBuffer(0));
    其中lpstraddr是我传进来的组播地址参数,没错吧
    调用wsasend时是这样的wsaswnd(m_sock,....m_srcaddr...)//
      

  3.   

    bind只是绑定本地地址,没看到你有加入多播组的代码呀,加入多播组要这样:
    /* 多播地址 */
        mcast_addr.imr_multiaddr.s_addr = inet_addr(SNTP_MCAST_ADDR);
        mcast_addr.imr_interface.s_addr = INADDR_ANY;    /* 加入多播组 */
        result = setsockopt(clt_soc, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                            (char *)&mcast_addr, sizeof(mcast_addr));我给你的链接中找SntpClnt程序,有加入多播组的代码.