如何从udp套接字(C / C ++)获取自己的(本地)IP地址

时间:2020-03-05 18:43:47  来源:igfitidea点击:
  • 我们有多个网络适配器。
  • 将UDP套接字绑定到本地端口,而不指定地址。
  • 在适配器之一上接收数据包。

我们如何获取接收到数据包的适配器的本地IP地址?

问题是,"接收器适配器的IP地址是什么?"而不是我们从发件人那里获得的地址

receive_from( ..., &senderAddr, ... );

称呼。

解决方案

回答

ssize_t
     recvfrom(int socket, void *restrict buffer, size_t length, int flags,
         struct sockaddr *restrict address, socklen_t *restrict address_len);

     ssize_t
     recvmsg(int socket, struct msghdr *message, int flags);

[..]
     If address is not a null pointer and the socket is not connection-oriented, the
     source address of the message is filled in.

实际代码:

`
int nbytes = recvfrom(sock,buf,MAXBUFSIZE,MSG_WAITALL,(struct sockaddr *)&bindaddr,&addrlen);

fprintf(stdout,"读取本地地址%s \ n上的%d个字节",nbytes,inet_ntoa(bindaddr.sin_addr.s_addr));
`

希望这可以帮助。

回答

我们可以枚举所有网络适配器,获取它们的IP地址,并将子网掩码覆盖的部分与发送者的地址进行比较。

喜欢:

IPAddress FindLocalIPAddressOfIncomingPacket( senderAddr )
{
    foreach( adapter in EnumAllNetworkAdapters() )
    {
        adapterSubnet = adapter.subnetmask & adapter.ipaddress;
        senderSubnet = adapter.subnetmask & senderAddr;
        if( adapterSubnet == senderSubnet )
        {
            return adapter.ipaddress;
        }
    }
}

回答

G'day,

我假设我们已经使用INADDR_ANY指定地址了。

如果是这种情况,则INADDR_ANY的语义是在所有接口上指定的端口上创建UDP套接字。套接字将获取所有发送到指定端口上所有接口的数据包。

使用此套接字发送时,使用编号最小的接口。传出发送者的地址字段设置为使用的第一个传出接口的IP地址。

执行ifconfig -a时,第一个传出接口定义为序列。可能是eth0。

HTH。

干杯,

回答

timbo提供的解决方案假定地址范围是唯一的,并且不重叠。虽然通常是这种情况,但这不是通用的解决方案。

在Steven的书" Unix网络编程"(第20.2节)中提供的功能可以很好地实现我们所要实现的功能,这是一个出色的实现。
这是基于recvmsg()而不是recvfrom()的函数。如果套接字启用了IP_RECVIF选项,则recvmsg()将返回在其上接收到数据包的接口的索引。然后可以使用它来查找目标地址。

源代码在这里可用。有问题的函数是" recvfrom_flags()"

回答

试试这个:

gethostbyname("localhost");