组播 - 没有这样的设备组播、设备

2023-09-04 23:47:04 作者:一身软妹味

我想用下面这段code连接到多播组:

I am trying to connect to a multicast group using the following piece of code:

 int flag_on = 1;              /* socket option flag */
  struct sockaddr_in mc_addr;   /* socket address structure */
  char recv_str[MAX_LEN+1];     /* buffer to receive string */
  int recv_len;                 /* length of string received */
  char* mc_addr_str;            /* multicast IP address */
  unsigned short mc_port;       /* multicast port */
  struct sockaddr_in from_addr; /* packet source */
  unsigned int from_len;        /* source addr length */


  mc_addr_str = ip;      /* arg 1: multicast ip address */
  mc_port = port;    /* arg 2: multicast port number */

  /* validate the port range */
  if ((mc_port < MIN_PORT) || (mc_port > MAX_PORT)) {
    fprintf(stderr, "Invalid port number argument %d.\n",
            mc_port);
    fprintf(stderr, "Valid range is between %d and %d.\n",
            MIN_PORT, MAX_PORT);
    exit(1);
  }

  /* create socket to join multicast group on */
 // if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  if ((sock = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP)) < 0) {
    perror("socket() failed");
  LOGE("*********Inside Join Multicast -- socket() failed*********");
    exit(1);
  }
  LOGE("Socket value  = %d ",sock);
  /* set reuse port to on to allow multiple binds per host */
  if ((setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag_on,
       sizeof(flag_on))) < 0) {
    perror("setsockopt() failed");
  LOGE("*********Inside Join Multicast -- socketopt() failed*********");

    exit(1);
  }

  /* construct a multicast address structure */
  memset(&mc_addr, 0, sizeof(mc_addr));
  mc_addr.sin_family      = AF_INET;
  mc_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  mc_addr.sin_port        = htons(mc_port);

  /* bind to multicast address to socket */
  if ((bind(sock, (struct sockaddr *) &mc_addr,
       sizeof(mc_addr))) < 0) {
    perror("bind() failed");
  LOGE("*********Inside Join Multicast -- bind() failed*********");
    exit(1);
  }

  /* construct an IGMP join request structure */
  mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str);
  mc_req.imr_interface.s_addr = htonl(INADDR_ANY);

  /* send an ADD MEMBERSHIP message via setsockopt */
  if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
       (void*) &mc_req, sizeof(mc_req))) < 0) {
    perror("setsockopt() failed");
  LOGE("*********Inside Join Multicast -- socketopt2() failed*********");
  LOGE("Value of errno is %s",strerror(errno));
 exit(1);
  }

和我收到的错误是errno的价值是没有这样的设备。

and the error I have received is Value of errno is No such device.

我想实现这一目标的OMAP板 - GB移植

I am trying to achieve this on omap board - GB ported.

能否请你帮忙。

推荐答案

我有一个非常类似的问题,虽然我用Java接口。 就我而言,我得到没有这样的设备的错误,直到我明确指出哪些接口应该是处理多播数据包。就我而言,这是一个以太网接口。 再次,这是不平静的情况下,由于您使用JNI,也因为你可能不需要eth0的,但我希望它会帮助:

I had a very similar problem, although I was using java interface. In my case, I was getting "No such device" error until I explicitly stated which interface should be handling multicast packets. In my case, that was an ethernet interface. Again this is not quiet your case, since you're using JNI, and also since you probably don't need eth0, but I hope it'll help:

Enumeration<NetworkInterface> enumeration = NetworkInterface.getNetworkInterfaces();
NetworkInterface eth0 = null;
while (enumeration.hasMoreElements() {
    eth0 = enumeration.nextElement()
    if (eth0.getName().equals("eth0")) {
        //there is probably a better way to find ethernet interface
        break;
    }
}

InetAddress group = InetAddress.getByName(IP);
MulticastSocket s = new MulticastSocket(PORT);
s.setSoTimeout(10000);
//s.joinGroup(group); //this will throw "No such device" exception 
s.joinGroup(new InetSocketAddress(group, PORT), eth0); // this works just fine

for (int i = 0; i < 10; ++i) {
    byte[] buf = new byte[8096];
    DatagramPacket recv = new DatagramPacket(buf, buf.length);
    s.receive(recv);
    System.out.println("Recieved " + recv.getLength() + " bytes.");
}

s.leaveGroup(group);

所以我猜的想法是,如果你有超过1接口,你应该明确哪一个是您使用指定。

So I guess the idea is that if you have more than 1 interface, you should explicitly specify which one are you using.