对于以下我假设一张网卡。
我有一个程序的组件,旨在让子网中的其他人知道它的存在。为此,我实现了一个解决方案,无论何时程序启动(以及之后定期),它都会向INADDR_BROADCAST
发送广播 - 无论谁收听所需端口,都会记住它来自哪里供以后使用。
这个问题是我不想记住我自己的广播。我认为理论上这很容易做 - 只需找出本地IP并与recvfrom
中的内容进行比较。
但是,我发现很难获得本地IP:getaddrinfo
返回NULL 127.0.0.1
,getaddrinfo
,主机名返回公共IP。任何人都可以指向我找到实际的子网IP的方向?我想我必须错过一些非常明显的东西,但是......我仍然错过了它。)
注意:我已经阅读了有关广播的其他SO问题,特别是这个问题:UDP-Broadcast on all interfaces但我尚未解决多接口问题。
答案 0 :(得分:7)
启动时,您可以使用随机(但跟踪)值广播不同的消息,然后等待该消息,发现您自己的地址,从那时起,您可以发送正常消息,忽略您的来源消息。 / p>
答案 1 :(得分:1)
getsockname
(function documentation)可以发现与特定套接字关联的本地IP地址。如果您在用于发送广播的套接字上拨打此电话,您应该会看到recvfrom
返回的相同IP地址。
答案 2 :(得分:1)
在linux上,您可以使用带有SIOCGIFADDR
选项的ioctl获取给定接口的IP地址。不过,我不认为这适用于Windows。为此,你必须做一些像this这样的傻瓜。
答案 3 :(得分:0)
搜索scoket选项并查看这些是否有效: IP_MULTICAST_LOOP,IP_BLOCK_SOURCE
答案 4 :(得分:0)
(我假设您正在使用Windows)
GetIpAddrTable正是这样做的!它返回有关所有网络接口的数据,其中包含IP地址。获得它们有一些技巧,但不会超过其他的Winsocks。
这是一个准备编译的54行示例,它打印所有带有IP和网络掩码的网络接口,还有本地回调的过滤器(127.0.0.1),因为你很可能不希望这样,并且它总是那里,所以你不能忽视它:
(使用msvc 19,Windows 10,链接Iphlpapi.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个Rep,所以我不知道我是否能够回答问题,谢谢Stackoverflow!)