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

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

我已经尝试过以下命令

sudo ifconfig lo multicast
sudo ip route add 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;
    }

最佳答案

您可以在环回时使用多播,但必须添加新的路由,因为默认情况下,您的操作系统使用默认的外部接口(interface)进行多播。默认情况下,回送时也可以禁用多播。在Linux上,您可以使用以下命令更改此设置:

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

10-06 09:51