2013-04-15 6 views
9

UDPマルチキャストパケットをループバックアドレスに送信し、他のアプリケーションで受信したいと考えています。すべてのテストはfedora core 17 Linuxで行われました。ループバックデバイスでのマルチキャスト

アイデアは、RTSP/HTTPまたは他のネットワークプロトコルを介してビデオストリームを受信して​​、私は、マルチキャストアドレスを使用してストリームを再生するためにVLCを使用できるように、ループバックアドレスでそれをマルチキャストすることです。他のビットレートと制御されたマルチキャストの問題を除いて、ループバックデバイスで1つのビデオファイルとマルチキャストを読み込もうとしました。しかし、vlcで同じことをしようとするとうまくいきませんでした。私は、パケットがWiresharkの中で送信さばかり見ることができるよしかしSRC IPは私のデフォルトのネットワーク・インターフェース(私のデフォルトゲートウェイ、すなわちインターフェース)から取られ

私はすでに

のsudo ifconfigコマンドは、次のコマンドを試してみましたLO をマルチキャストsudoのIPルートこの点で任意の提案は非常に参考になる239.252.10.10のdevのLO

を追加します。

  #include <sys/types.h> 
    #include <sys/socket.h> 
    #include <arpa/inet.h> 
    #include <netinet/in.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <unistd.h> 


    #define MULTICAST_ADDRESS "239.252.10.10" 
    #define UDP_PORT 1234 
    #define INTERFACE_IP "127.0.0.1" 
    #define MTU 1474 
    #define DATA_BUFFER_SIZE (1024*1024) 

    static int socket_init(char *intf_ip) { 
    int sd; 
    struct in_addr localInterface; 

     sd = socket (AF_INET, SOCK_DGRAM, 0); 
     if (sd < 0) { 
      perror ("Opening datagram socket error"); 
      return -1; 
     } 
     else 
     printf ("Opening the datagram socket...OK.\n"); 

     localInterface.s_addr = inet_addr (intf_ip); 

     if (setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &localInterface,sizeof (localInterface)) < 0){ 
      perror ("Setting local interface error"); 
      close(sd); 
      return -1; 
     } 
     else 
     printf ("Setting the local interface...OK\n"); 
    #if 1 
     char loopch = 1; 

     if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopch, sizeof(loopch)) < 0){ 
     perror("Setting IP_MULTICAST_LOOP error"); 
     close(sd); 
     return -1; 
     } 
     else 
     printf("Enabling the loopback...OK.\n"); 
    #endif 
     return sd; 

    } 


    static int transmit_packet(int sd, char *databuf, int size,char *ip, unsigned short port){ 

    struct sockaddr_in groupSock; 
    int len,datalen,rc; 

     memset ((char *) &groupSock, 0, sizeof (groupSock)); 

     groupSock.sin_family = AF_INET; 

     groupSock.sin_addr.s_addr = inet_addr (ip); 

     groupSock.sin_port = htons (port); 

     len=0; 
     datalen = MTU; 
     if(size < MTU) 
     datalen = size; 

     while(len < size){ 
     rc = sendto(sd, databuf, datalen, 0, (struct sockaddr *) &groupSock,sizeof (groupSock)); 
     if(rc <0){ 
      perror ("Sending datagram message error"); 
      return -1; 
     } 
     usleep(10000); 
     len += rc; 
     } 
     return len; 
    } 

    static int transmit_file(char *filepath, char *dstip, char *srcip,unsigned short port) { 
    FILE *fp; 
    int sd,rc; 
    char *databuf; 


     fp = fopen(filepath, "r"); 
     if(!fp) { 
     printf("transmit_file : no such file or directory %s \n",filepath); 
     return -1; 
     } 
     sd = socket_init(srcip); 
     if(sd < 0) { 
     printf("Socket initialization failed \n"); 
     fclose(fp); 
     return -1; 
     } 
     databuf = (char*) malloc(sizeof(char)*DATA_BUFFER_SIZE); 
     if(!databuf) { 
     printf("Unable to allocate databuf\n"); 
     close(sd);fclose(fp); 
     return -1; 
     } 
     while(!feof(fp)){ 
     rc = fread(databuf,1,DATA_BUFFER_SIZE,fp); 
     if(rc<= 0) { 
      printf("read failed or EOF reached\n"); 
      break; 
     }   
     if(transmit_packet(sd,databuf,rc,dstip,port) <0) 
      printf("Transmit failed\n");  
     } 
     close(sd);fclose(fp); 
     free(databuf); 
     return 0; 
    } 

    int main(int argc, char *argv[]){ 

     if(argc != 3){ 
     printf("%s <filename> <ip>\n",argv[0]); 
     return -1; 
     } 
     transmit_file(argv[1],argv[2],INTERFACE_IP,UDP_PORT); 
     return 0; 
    } 
+0

あなたには解決策がありましたか?私も同じ問題があります。 – user2990252

答えて

0

の下に貼り付けられたテスト・プログラム・コードIは、アドレス

すぐそこに停止をループバックするためにUDPマルチキャストパケットを送りたいです。あなたはそれをすることはできません。それは不可能だ。マルチキャストアドレスにのみマルチキャストを送信できます。あなたのコードはマルチキャストを行わず、ただ127.0.0.1に送信します。

ローカルホストに送信する場合は、なぜマルチキャストを使用していますか?複数のリスニングプロセスがありますか?

あなたのソケットをバインドされていないとして、SRC IPは、私のデフォルトのネットワーク・インターフェース(私のデフォルトゲートウェイであるすなわちインターフェース)

から非常に可能性が取られています。あなたは何を期待しましたか?

+0

マルチキャストアドレスは、宛先IPとするコマンドラインから与えることができます。基本的に私はマルチキャストでループバックインターフェイスに受信したものを送信して、別のアプリケーションが再生している間に1つのアプリケーションがファイルに記録できるようにしたい。そのため、udpパケットの宛先IPに対してマルチキャスト宛先が設定されます。 –

+0

インターフェイスsrc ipに対して、ソケットを127.0.0.1にバインドしても、それでも送信パケットでそれを受け取ることはありません。 –

+2

@EJP複数のプロセスを1つのストリームからサブ/パブの方法で読み取らせたい場合はどうすればよいですか?例えばライブ映像。 – Aron

13

あなたは、ループバックでマルチキャストを使用することができますが、あなたのOSは、マルチキャストのために、デフォルトでデフォルトの外部インタフェースを使用しているため、新たなルートを追加する必要があります。また、マルチキャストは、ループバック時にデフォルトで無効にすることができます。 Linuxでは、次のコマンドでこれを変更することができます:

route add -net 224.0.0.0 netmask 240.0.0.0 dev lo 
ifconfig lo multicast 
関連する問題