根据<<windows网络编程技术>>上面说的,实现多播有两种方式,一是使用有根多播,二是使用无根多播。有根多播要客户将多播信息返回服务器,再由服务器发送给每个客户。
无根多播要加入一个多播组,凡在多播组中的客户都可能收到客户向多播组发送的信息。谁能给我实现这两种方法的源代码?

解决方案 »

  1.   

    上面的代码是根据书上所讲而写的,但下面的代码我测试过了。
    发送端为本机,接收端为互联网络上的一台服务器,但接收端却收不到多播,
    是怎么回事?组播通讯:
    ////////////////////send.c////////////////////////////
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdio.h>#define BUFFSIZE 2048
    #define IP_ADDR      "224.8.8.1"     
    #define DEST_PORT         8888int main(int argc,char *argv[])
    {
        int sockfd;
        struct sockaddr_in addr;
        char szError[100];
    char buf[] = "Hello, World!";
    int ttl = 255 ; // Arbitrary TTL value.    WSADATA WSAData;
        WORD  wVersionRequested;
        wVersionRequested = MAKEWORD(2, 2);
       if (WSAStartup (wVersionRequested , &WSAData) != 0) 
        {
            printf ("recver:Initialize Winsock error!");
            exit(1);
        }
        if (LOBYTE(WSAData.wVersion) != 2 || HIBYTE(WSAData.wVersion) != 2 ) {
            WSACleanup( );
            printf ("setsockopt failed! Error: %d", WSAGetLastError ());
            exit(1);
        }     addr.sin_family = AF_INET;
        addr.sin_port = htons(DEST_PORT);
        addr.sin_addr.s_addr = inet_addr(IP_ADDR);
        
        if ((sockfd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
            printf("sender:new a socket error!\n");
            exit(1);    
        } if(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl))!=0) 
    {
    printf("error setsockopt IP_MULTICAST_TTL\n");
    exit(1);
    }
    /*
        if (bind(sockfd,(struct sockaddr *)&recver_addr,sizeof(recver_addr)) < 0) {
            closesocket(sockfd);
            printf("recver:bind socket error!\n");
            exit(1);    
        }
    */
        
      if (sendto (sockfd, buf, sizeof(buf) , 0, (struct sockaddr *)&addr, sizeof(addr))
    == SOCKET_ERROR)
      {
        wsprintf (szError, TEXT("sendto failed! Error: %d"), 
                  WSAGetLastError ());
        MessageBox (NULL, szError, TEXT("Error"), MB_OK);
        closesocket (sockfd);
        return FALSE;
      }
      else
      {
        printf("send ok\n");
      } // Close Sock.
    closesocket (sockfd);
    WSACleanup ();
    return 0;
    }
    ////////////////////send.c/////////////////////////////////////////////////////////receive.c////////////////////////////
    //#include <windows.h>
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdio.h>#define BUFFSIZE 2048
    #define RECV_IP_ADDR      "224.8.8.1"     
    #define DEST_PORT         8888int main(int argc,char *argv[])
    {
        int sockfd;
        int sock_reuse = 1;
        struct ip_mreq multicast;
        struct sockaddr_in recver_addr;
        char szError[100];  int index = 0,                      // Integer index
          iRecvLen;                       // Length of recv_sin
      char szMessageA[1024*320];               // ASCII string 
      TCHAR szMessageW[1024*320];              // Unicode string
        
        WSADATA WSAData;
        WORD  wVersionRequested;
        wVersionRequested = MAKEWORD(2, 2);
        if (WSAStartup (wVersionRequested , &WSAData) != 0) 
        {
            printf ("recver:Initialize Winsock error!");
            exit(1);
        }
        if (LOBYTE(WSAData.wVersion) != 2 || HIBYTE(WSAData.wVersion) != 2 ) {
            WSACleanup( );
            printf ("setsockopt failed! Error: %d", WSAGetLastError ());
            exit(1);
        }     multicast.imr_multiaddr.s_addr = inet_addr(RECV_IP_ADDR);
        multicast.imr_interface.s_addr = htonl(INADDR_ANY);
        recver_addr.sin_family = AF_INET;
        recver_addr.sin_port = htons(DEST_PORT);
        recver_addr.sin_addr.s_addr = INADDR_ANY;
        
        if ((sockfd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
            printf("recver:new a socket error!\n");
            exit(1);    
        }
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&sock_reuse, sizeof(sock_reuse)) < 0) {
              printf("recver : socket options set error");
              exit(1);
        }    if (bind(sockfd,(struct sockaddr *)&recver_addr,sizeof(recver_addr)) < 0) {
            closesocket(sockfd);
            printf("recver:bind socket error!\n");
            exit(1);    
        }
        
        if (setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *)&multicast,sizeof(multicast)) < 0 ) {
            sprintf (szError, TEXT("setsockopt failed! Error: %d"), WSAGetLastError ());
            printf("%s\n", szError);
            closesocket(sockfd);
            exit(1);
        } printf("Receive on %s:%d\n", RECV_IP_ADDR, DEST_PORT);
      iRecvLen = sizeof (recver_addr);
      memset(szMessageA, 0, sizeof(szMessageA));
      // Receive data from the multicasting group server.
      if (recvfrom (sockfd, 
                    szMessageA,
                    sizeof(szMessageA),         
                    0,
                    (struct sockaddr FAR *) &recver_addr,
                    &iRecvLen) == SOCKET_ERROR)
      {
        wsprintf (szError, TEXT("recvfrom failed! Error: %d"), 
                  WSAGetLastError ());
        MessageBox (NULL, szError, TEXT("Error"), MB_OK);
        closesocket (sockfd);
        return FALSE;
      }
      else
      {
        // Convert the ASCII string to a Unicode string.
        for (index = 0; index <= sizeof (szMessageA); index++)
          szMessageW[index] = szMessageA[index];    MessageBox (NULL, szMessageW, TEXT("Info"), MB_OK);
      }  // Disable receiving on Sock before closing it.
      shutdown (sockfd, 0x00);  // Close Sock.
      closesocket (sockfd);  WSACleanup ();
        return 0;
    }
    /////////////////////////////receive.c////////////////////////////