UDP接收忽略来自自己地址的广播

时间:2014-04-24 20:58:43

标签: linux sockets networking udp broadcast

我有我认为是一种奇怪的可重复行为。我有一个孤立的网络。在启动时,几个嵌入式Linux设备将以相同的IP地址启动。我们的想法是让他们使用UDP广播发送带有唯一标识符的标识包,然后他们就可以整理出他们的地址。但是,我所看到的是每个设备都可以接收自己的广播数据包,但它不会从具有相同IP地址的其他设备接收广播数据包。从已经分配了非冲突地址的设备接收广播数据包没有问题。我已经使用嵌入式Linux设备和Linux PC的混合测试代码,但结果是一样的。广播接收仅在从非您自己的地址发送时才有效。是否存在一些较低级别的网络限制。

以下是套接字设置的代码

  sintn sn_broadcast_listen_socket_create(void)
  {
     sintn sn_sckt;
     struct sockaddr_in t_me;

     mt_own_address.sin_addr.s_addr = INADDR_ANY;
     ms16_print_addresses(AF_INET, OUR_INTERFACE, TRUE, &mt_own_address);

     sn_sckt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
     if (sn_sckt < 0)
     {
        printf("sn_broadcast_listen_socket_create-socket:(%d)%s\n", errno, strerror(errno));
     }
     else
     {
        memset(&t_me, 0, sizeof(t_me));
        t_me.sin_family = AF_INET;
        t_me.sin_port = htons(MODBUS_IP_PORT);
        t_me.sin_addr.s_addr = htonl(INADDR_ANY);

        if (bind(sn_sckt, (struct sockaddr*)&t_me, sizeof(t_me)) < 0)
        {
           printf("sn_broadcast_listen_socket_create-bind:(%d)%s\n", errno, strerror(errno));
           sn_sckt = -1;
        }
     }

     return sn_sckt;
  }

  sintn sn_broadcast_socket_create(void)
  {
     sintn sn_mysocket;
     sintn broadcastEnable = TRUE;

     sn_mysocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
     if (sn_mysocket < 0)
     {
        printf("sn_broadcast_socket_create-socket:(%d)%s\n", errno, strerror(errno));
     }
     else if (setsockopt(sn_mysocket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable)) < 0)
     {
        printf("sn_broadcast_socket_create-setsockopt:(%d)%s\n", errno, strerror(errno));
        sn_mysocket = -1;
     }

     return sn_mysocket;
  }


  sint16 s16_broadcast_send(sintn osn_bsocket, uint32 ou32_address, uint16 ou16_port, T_modbus_adu *opt_mb_adu, uint16 ou16_size)
  {
     struct sockaddr_in t_other;
     sint16 s16_rval = C_NO_ERR;


     memset(&t_other, 0, sizeof(t_other));
     t_other.sin_family = AF_INET;

     t_other.sin_port = htons(ou16_port);
     t_other.sin_addr.s_addr = htonl(ou32_address);

     if (sendto(osn_bsocket, opt_mb_adu, ou16_size, 0, (struct sockaddr*)&t_other, sizeof(t_other)) < 0)
     {
        printf("s16_broadcast_send-sendto:(%d)%s\n", errno, strerror(errno));
        s16_rval = C_UNKNOWN_ERR;
     }

     return s16_rval;
  }

接收由套接字上的read select()触发。发送目标地址为INADDR_NONE。就像我之前说的那样,只要广播发送者和广播接收者拥有不同的IP地址,一切都会有效。

0 个答案:

没有答案