环回设备上的组播 [英] Multicasting on the loopback device

查看:95
本文介绍了环回设备上的组播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望将UDP多播数据包发送到回送地址,并在其他应用程序中接收该数据包.所有测试均在fedora core 17 Linux上完成.

I wish to send UDP multicast packets to loopback address and receive the same in other application. All tests done on fedora core 17 Linux.

这个想法是通过RTSP/HTTP或任何其他网络协议接收视频流,并在环回地址上对其进行多播,以便我可以使用VLC通过多播地址播放该流.除了其他比特率和受控制的多播问题之外,我尝试读取一个视频文件并在回送设备上进行多播.但是,当尝试在vlc上播放相同内容时,它没有效果.我能够看到数据包正在Wireshark中传输,但是src ip是从我的默认网络接口(即我的默认网关的接口)中获取的

The idea is to receive a video stream via RTSP/HTTP or any other network protocol and multicast it on the loopback address so that I can use VLC to play the stream using multicast address. Leaving aside other bitrate and controlled multicast issues, I tried to read one video file and multicast on loopback device. But when tried to play the same on vlc it didn't worked. I'm able to see packet getting transmitted in wireshark but the src ip is taken from my default network interface (i.e interface which is my default gateway)

我已经尝试过以下命令

sudo ifconfig lo multicast
sudo ip route add 239.252.10.10 dev lo

在这方面的任何建议都将非常有帮助.

Any suggestion in this regard would be very helpful.

下面粘贴的测试程序代码

Test program code pasted below

    #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;
    }

推荐答案

您可以在环回中使用多播,但是您必须添加一条新路由,因为您的操作系统默认使用默认的外部接口进行多播.默认情况下,在环回时也可以禁用多播.在Linux上,您可以使用以下命令对此进行更改:

You can use multicast on loopback but you have to add a new route because your OS using default external interface by default for multicast. Also multicast can be disabled by default on loopback. On linux you can change this with this command :

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

这篇关于环回设备上的组播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆