#define satosin(sa) ((struct sockaddr_in *)(sa))

int sockMult;
char * multIP;
struct sockaddr_in local;
struct sockaddr_in client;
struct ip_mreq mreq;
struct ip_mreq_intf  ipmreq_intf;
int multport;
char option;
int bufsize;
char ret;
int i; int  len; void * buf;
UInt32  msg_buf[4];
int len1;
int retNum;
int port;
UInt32  sendbuf = 32 * 1024;
int  res;
int setcsum=1;
int setTTL = 1;

bufsize = 1024 ;
option  = 64;
ret = 0;
port = 6666;

sockMult = socket(AF_INET, SOCK_DGRAM, 0);

ioctlsocket(sockMult,SIOCSUDPCHKSUM,(char*)&setcsum);
    ioctlsocket(sockMult,SIOCSIPDEFAULTTTL,(char*)&setTTL) ;
   
setsockopt(sockMult,SOL_SOCKET,SO_SNDBUF, (char*)&sendbuf, 4);
   
    res = setsockopt(sockMult,IPPROTO_IP,IP_MULTICAST_TTL, (char*)&option, sizeof(char)); //跨越路由器个数 
    if( res == -1 )
    osdPrintf(3,3,1,"ttl err");
    res = setsockopt(sockMult,IPPROTO_IP,IP_MULTICAST_LOOP, (char*)&ret, sizeof(char)); //允许多播返回
    if( res == -1 )
    osdPrintf(5,5,1,"loop err");
   
    local.sin_family      = AF_INET;
    local.sin_addr.s_addr = htonl(INADDR_ANY);
    local.sin_port        = htons(port);
    memset((char*)local.sin_zero, 0, 8);
   
    bind(sockMult,(Pointer)(&local),sizeof( struct sockaddr_in) );
   
    ipmreq_intf.imrif_mcastaddr.s_addr = htonl(inet_addr("239.193.1.1"));
ipmreq_intf.imrif_ifno = 1;

res = setsockopt(sockMult, IPPROTO_IP, IP_ADD_MEMBERSHIP_INTF, (char *)&ipmreq_intf,sizeof(struct ip_mreq_intf));
if( res == -1 )
    osdPrintf(10,10,1,"add multi inif err");
   
    memset( &mreq,0,sizeof(mreq) );
    mreq.imr_mcastaddr.s_addr = inet_addr("239.193.1.1");
    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
   
    if( mreq.imr_mcastaddr.s_addr == -1 )
      osdPrintf(2,2,1,"multi ip err");  
    res = setsockopt( sockMult,IPPROTO_IP,IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(struct ip_mreq) ); //加入多播组
    if( res == -1 )
    osdPrintf(6,6,1,"add multi err");
    len = sizeof( struct sockaddr_in );
    memset(&client, 0, 8);

解决方案 »

  1.   

    加入多播的时候报错
    res = setsockopt( sockMult,IPPROTO_IP,IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(struct ip_mreq) ); //加入多播组为什么呢?
      

  2.   

    组播不需要什么特殊的设置。下面是的代码在win2k 局域网环境下试验通过://发送方程序 sender.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;
    }// 接收方程序 receivers.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;
    }
    codeguru上也有个多播的类
      

  3.   

    http://www.upsoft.com.cn/download
    我这里有一个vc的多播程序,可以编译的哦