写了两个简单的控制台程序:Sender和Receiver,用于发送接收组播消息。   
  代码如下:   
  ------------------------------------Sender.c   
  #include   "stdafx.h"   
    
  #include   <winsock2.h>   
  #include   <ws2tcpip.h>   
  #include   <stdio.h>   
  #include   <stdlib.h>   
    
  #define   MCASTADDR   "224.0.1.0" //本例使用的多播组地址。   
  #define   MCASTPORT   6701 //本地端口号。   
  #define   BUFSIZE       1024 //发送数据缓冲大小。   
    
  #pragma   comment(lib,   "Ws2_32.lib")   
    
  int   main(int   argc,   char*   argv[])   
  {   
  struct   sockaddr_in   remote;   
  SOCKET   sock,sockM;   
  TCHAR   sendbuf[BUFSIZE];   
  int   len   =   sizeof(   struct   sockaddr_in);   
    
  //   初始化WinSock2.2   
  WSADATA   wsd;   
  if(   WSAStartup(   MAKEWORD(2,2),&wsd)   !=   0   )   
  {   
  printf("WSAStartup()   failed\n");   
  return   -1;   
  }   
    
  if((sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|   
  WSA_FLAG_OVERLAPPED))   ==   INVALID_SOCKET)   
  {   
  printf("socket   failed   with:%d\n",WSAGetLastError());   
  WSACleanup();   
  return   -1;   
  }   
    
  //   加入多播组   
  remote.sin_family   =   AF_INET;   
  remote.sin_port   =   htons(MCASTPORT);   
  remote.sin_addr.s_addr   =   inet_addr(   MCASTADDR   );   
  if((   sockM   =   WSAJoinLeaf(sock,(SOCKADDR*)&remote,sizeof(remote),NULL,NULL,NULL,NULL,   
  JL_BOTH))   ==   INVALID_SOCKET)   
  {   
  printf("WSAJoinLeaf()   failed:%d\n",WSAGetLastError());   
  closesocket(sock);   
  WSACleanup();   
  return   -1;   
  }   
    
  //   发送多播数据,当用户在控制台输入"QUIT"时退出。   
  while(1)   
  {   
  printf("SEND   :   ");   
  scanf("%s",sendbuf);   
  if(   sendto(sockM,(char*)sendbuf,strlen(sendbuf),0,(struct     
  sockaddr*)&remote,sizeof(remote))==SOCKET_ERROR)   
  {   
  printf("sendto   failed   with:   %d\n",WSAGetLastError());   
  closesocket(sockM);   
  closesocket(sock);   
  WSACleanup();   
  return   -1;   
  }   
  if(strcmp(sendbuf,"QUIT")==0   ||   strcmp(sendbuf,   "quit")==0)     
  break;   
  Sleep(500);   
  }   
    
  closesocket(sockM);   
  closesocket(sock);   
  WSACleanup();   
    
  return   0;   
  }   
    
    
  -----------------------------------------Receiver.c   
  #include   "stdafx.h"   
    
  #include   <winsock2.h>   
  #include   <ws2tcpip.h>   
  #include   <stdio.h>   
  #include   <stdlib.h>   
    
  #define   MCASTADDR   "224.0.1.0" //本例使用的多播组地址。   
  #define   MCASTPORT   6701 //绑定的本地端口号。   
  #define   BUFSIZE       1024 //接收数据缓冲大小。   
    
  #pragma   comment(lib,   "Ws2_32.lib")   
    
  int   main(int   argc,   char*   argv[])   
  {   
  struct   sockaddr_in   local;   
  struct   sockaddr_in   remote;   
  struct   sockaddr_in   from;   
  SOCKET   sock,sockM;   
  TCHAR   recvbuf[BUFSIZE];   
  /*struct   ip_mreq   mcast;   //   Winsock1.0   */   
    
  int   len   =   sizeof(struct   sockaddr_in);   
  int   ret;   
  //初始化WinSock2.2   
  WSADATA   wsd;   
  if(   WSAStartup(   MAKEWORD(2,2),&wsd)   !=   0   )   
  {   
  printf("WSAStartup()   failed\n");   
  return   -1;   
  }   
    
    
  /*创建一个SOCK_DGRAM类型的SOCKET   
  其中,WSA_FLAG_MULTIPOINT_C_LEAF表示IP多播在控制面层上属于"无根"类型;   
  WSA_FLAG_MULTIPOINT_D_LEAF表示IP多播在数据面层上属于"无根",有关控制面层和   
  数据面层有关概念请参阅MSDN说明。*/   
  if((sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,   
  WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED))   ==   INVALID_SOCKET)   
  {   
  printf("socket   failed   with:%d\n",WSAGetLastError());   
  WSACleanup();   
  return   -1;   
  }   
    
  //将sock绑定到本机某端口上。   
  local.sin_family   =   AF_INET;   
  local.sin_port   =   htons(MCASTPORT);   
  local.sin_addr.s_addr   =   htonl(INADDR_ANY);   
  if(   bind(sock,(struct   sockaddr*)&local,sizeof(local))   ==   SOCKET_ERROR   )   
  {   
  printf(   "bind   failed   with:%d   \n",WSAGetLastError());   
  closesocket(sock);   
  WSACleanup();   
  return   -1;   
  }   
    
  //加入多播组   
  remote.sin_family   =   AF_INET;   
  remote.sin_port   =   htons(MCASTPORT);   
  remote.sin_addr.s_addr   =   inet_addr(   MCASTADDR   );   
    
  /*   Winsock1.0   */   
  /*   
          mcast.imr_multiaddr.s_addr   =   inet_addr(MCASTADDR);   
          mcast.imr_interface.s_addr   =   INADDR_ANY;   
          if(     
          setsockopt(sockM,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast))     
    ==   SOCKET_ERROR)   
          {   
  printf("setsockopt(IP_ADD_MEMBERSHIP)   failed:%d\n",WSAGetLastError());   
  closesocket(sockM);   
               WSACleanup();   
               return   -1;   
          }   
  */   
          /*   Winsock2.0*/   
          if((   sockM   =   WSAJoinLeaf(sock,(SOCKADDR*)&remote,sizeof(remote),NULL,NULL,NULL,NULL,JL_BOTH))   ==   INVALID_SOCKET)   
  {   
  printf("WSAJoinLeaf()   failed:%d\n",WSAGetLastError());   
  closesocket(sock);   
  WSACleanup();   
  return   -1;   
  }   
    
  //接收多播数据,当接收到的数据为"QUIT"时退出。   
  while(1)   
  {   
  if((   ret   =   recvfrom(sock,recvbuf,BUFSIZE,0,(struct   sockaddr*)&from,&len))   ==   SOCKET_ERROR)   
  {   
  printf("recvfrom   failed   with:%d\n",WSAGetLastError());   
  closesocket(sockM);   
  closesocket(sock);   
  WSACleanup();   
  return   -1;   
  }   
  if(   strcmp(recvbuf,"QUIT")   ==   0   )   
  break;   
  else   
  {   
  recvbuf[ret]   =   '\0';   
  printf("RECV:'   %s   '   FROM   <%s>   \n",recvbuf,inet_ntoa(from.sin_addr));   
  }   
  }   
    
  closesocket(sockM);   
  closesocket(sock);   
  WSACleanup();   
    
  return   0;   
  }   
  请问一下使用预留多播地址为224.0.1.0~238.255.255.255,可用于全球范围(如Internet)或网络协议 为什么不能在英特网上组播呢?请知道的高手指教

解决方案 »

  1.   

    加入同一组播地址的计算机之间的路由器必须都支持组播,并且组播的“距离”受到TTL值限制广域网的组播还是一个待解决的问题。
    设想一个例子,
    假设你加入了多播组224.0.1.x,你想通过Internet组播,这就要求TTL值无穷大。离你最近的路由器将你加入x组的信息发送给相邻的路由器,下一路由器又将信息继续传递出去。由于TTL的无穷大这个信息将全球范围内传递,结果是你导致了全球网络的瘫痪。
      

  2.   

    特此说明一下,上面的例子纯属虚构,不要误导了小朋友想了解组播协议可以参见《TCP/IP详解 卷1:协议》
      

  3.   

    设置组播传播范围(TTL)的Socket APIWSAIoctl(hSocket, SIO_MULTICAST_SCOPE,
        &nTTL, sizeof(nTTL),
        NULL, 0,
        (PULONG)&cbRet,
        NULL, NULL);
      

  4.   

    Internet组播...哈哈,有点常识好不好
      

  5.   

    WO,WO 我这苦命的孩子,要如何决这个问题,QQ、MSN是如何实现群发的呢,有没有相关参考资料呢?
      

  6.   

    在Internet上不能使用,路由器一般都不会允许的,你还是想其他办法好了.
      

  7.   

    谢谢sunnyroad与vocanicy(刺客)的回答,我看TCP/IP的协议答案是一样的,关键是我现在实在太急用,不然方法很多种。