代码之家  ›  专栏  ›  技术社区  ›  laura

如何忽略您自己的广播udp数据包

  •  8
  • laura  · 技术社区  · 16 年前

    我的程序中有一个组件,用于让子网中的其他人知道它的存在。为此,我实现了一个解决方案,每当程序启动时(以及之后的定期启动),它都会向用户发送广播 INADDR_BROADCAST -任何在所需端口上侦听的人都将记住该端口的来源,以便以后使用。

    问题是我不想记住我自己的广播。我认为从理论上讲,这很容易做到——只需找出本地ip,并与您得到的进行比较 recvfrom .

    但是,我发现很难获得本地IP: getaddrinfo 返回为空 127.0.0.1 , getaddrinfo 使用主机名返回公共ip。有人能告诉我找到实际子网ip的方向吗?我想我一定错过了一些很明显的东西,但是。。。我还是不知道:)

    UDP-Broadcast on all interfaces 但我还没有谈到多接口问题。

    5 回复  |  直到 8 年前
        1
  •  8
  •   Simeon Pilgrim    16 年前

    在启动时,你可以用随机(但跟踪)值广播不同的消息,然后等待该消息,以发现你自己的地址,从那时起,你可以发送普通消息,忽略你的源消息。

        2
  •  2
  •   user214921 user214921    16 年前

    SIOCGIFADDR 选项不过,我认为这对Windows不起作用。为此,你得做些傻事,比如 this .

        3
  •  1
  •   Left For Archive    16 年前

    getsockname ( function documentation )可以发现与特定套接字关联的本地IP地址。如果您在用于发送广播的套接字上调用它,您应该会看到返回的相同IP地址 recvfrom .

        4
  •  0
  •   Priyank Bolia    16 年前

    搜索scoket选项并查看这些选项是否有效:

        5
  •  0
  •   pulp_user    8 年前

    (我猜您正在Windows上工作)

    GetIpAddrTable 确实如此!它返回有关所有网络接口的数据,其中包括IP地址。在获得它们的过程中有一些诡计,但并不比Winsocks的其余部分更为诡计。

    下面是一个准备编译的54行示例,它使用IP和网络掩码打印您的所有网络接口,并为您的本地回调(127.0.0.1)进行筛选,因为您很可能不希望这样,而且它总是存在,所以您不能忽略它:

    (与msvc 19、windows 10、针对iphlapi.lib和Ws2_32.lib的链接一起使用)

    #include "stdio.h"
    #include "Winsock2.h"
    #include "Iphlpapi.h"
    
    int main(){
        int error;
    
        ULONG size = 0;
        MIB_IPADDRTABLE* meta_table = nullptr;
    
        error = GetIpAddrTable(meta_table, &size, false);
        if(error != ERROR_INSUFFICIENT_BUFFER)
            return -1;
    
        meta_table = (MIB_IPADDRTABLE*)malloc(size);
    
        error = GetIpAddrTable(meta_table, &size, false);
        if(error != NO_ERROR)
            return -1;
    
        int os_interface_count = meta_table->dwNumEntries;
    
        for(int i = 0; i < os_interface_count; i++){
    
            printf("interface:\n");
    
            {
                in_addr mask;
                in_addr address;
                address.S_un.S_addr = meta_table->table[i].dwAddr;
                mask.S_un.S_addr = meta_table->table[i].dwMask;
    
                printf("index:     %d\n", meta_table->table[i].dwIndex);
                printf("address:   %s\n", inet_ntoa(address));
                printf("mask:      %s\n", inet_ntoa(mask));
            }
    
            {
                in_addr callback_address;
                callback_address.S_un.S_un_b.s_b1 = 127;
                callback_address.S_un.S_un_b.s_b2 = 0;
                callback_address.S_un.S_un_b.s_b3 = 0;
                callback_address.S_un.S_un_b.s_b4 = 1;
    
                if(meta_table->table[i].dwAddr == callback_address.S_un.S_addr)
                    printf("local callback!\n");
    
            }
    
        }
    
        free(meta_table);
        return 0;
    }
    

    在我的机器上生成此输出:

    interface:
    index:     7
    address:   192.168.56.1
    mask:      255.255.255.0
    interface:
    index:     1
    address:   127.0.0.1
    mask:      255.0.0.0
    local callback!
    interface:
    index:     11
    address:   192.168.178.181
    mask:      255.255.255.0
    

    唯一真正奇怪的是第一次打电话给 GetIpAddrTable ,它只提供需要为缓冲区分配的大小。我认为代码的其余部分是非常不言自明的,如果不是的话,我是来提问的(我没有50个代表,所以我不知道我是否能够回答问题,谢谢

    推荐文章