2013-04-15 28 views
9

Tôi muốn gửi các gói multicast UDP đến địa chỉ loopback và nhận được giống nhau trong ứng dụng khác. Tất cả các thử nghiệm được thực hiện trên Fedora core 17 Linux. Ý tưởng là nhận luồng video qua RTSP/HTTP hoặc bất kỳ giao thức mạng nào khác và phát đa hướng nó trên địa chỉ loopback để tôi có thể sử dụng VLC để phát luồng bằng địa chỉ multicast. Bỏ qua các bitrate khác và kiểm soát các vấn đề phát đa hướng, tôi đã cố gắng đọc một tệp video và thiết bị phát đa hướng trên thiết bị loopback. Nhưng khi cố gắng để chơi tương tự trên vlc nó đã không làm việc. Tôi có thể nhìn thấy gói bị truyền trong Wireshark nhưng ip src được lấy từ giao diện mạng mặc định của tôi (tức là giao diện mà là default gateway của tôi)Multicasting trên thiết bị loopback

Tôi đã thử lệnh

sudo ifconfig lo multicast sau sudo ip route thêm 239.252.10.10 dev lo

Bất kỳ đề xuất nào về vấn đề này sẽ rất hữu ích.

mã chương trình thử nghiệm dán bên dưới

  #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

bạn có giải pháp nào không ?? tôi cũng có cùng một vấn đề. – user2990252

Trả lời

0

tôi muốn gửi UDP gói tin multicast cho loopback địa chỉ

Dừng ngay tại đó. Bạn không thể làm điều đó. Điều đó là không thể. Bạn chỉ có thể gửi multicast đến các địa chỉ multicast. Mã của bạn không thực hiện bất kỳ phát đa hướng nào, chỉ cần gửi tới 127.0.0.1.

Nếu bạn chỉ gửi đến máy chủ cục bộ, tại sao bạn sử dụng phát đa hướng? Bạn có nhiều quy trình nghe không?

ip src được lấy từ giao diện mạng mặc định của tôi (nghĩa là giao diện mà là default gateway của tôi)

Rất có khả năng, như bạn đã không bị ràng buộc ổ cắm của bạn. Những gì bạn đã mong đợi?

+0

Địa chỉ multicast có thể được đưa ra từ dòng lệnh được lấy làm ip đích. Về cơ bản tôi muốn truyền tải bất cứ điều gì tôi nhận được để loopback giao diện trong một cách multicast để một ứng dụng có thể nhận được nó để ghi lại trong một tập tin trong khi một ứng dụng chơi nó và như vậy. Đó là lý do tại sao multicast đích được thiết lập cho ip đích của gói tin udp. –

+0

Đối với giao diện src ip ngay cả khi tôi liên kết ổ cắm với 127.0.0.1, nó vẫn không nhận được điều đó trong các gói đi. –

+2

@EJP Điều gì xảy ra nếu tôi muốn có nhiều quy trình đọc từ một luồng trong một loại phụ/quán rượu? Ví dụ: video trực tiếp. – Aron

13

Bạn có thể sử dụng tính năng phát đa hướng trên loopback nhưng bạn phải thêm tuyến mới vì hệ điều hành của bạn sử dụng giao diện mặc định bên ngoài theo mặc định cho phát đa hướng. Ngoài ra multicast có thể được tắt theo mặc định trên loopback. Trên linux, bạn có thể thay đổi điều này bằng lệnh này:

route add -net 224.0.0.0 netmask 240.0.0.0 dev lo 
ifconfig lo multicast