在python中确定已连接接口(linux)的IP地址

在python中确定已连接接口(linux)的IP地址,python,linux,networking,ip-address,Python,Linux,Networking,Ip Address,在我的linux机器上,3个网络接口中的1个可能实际连接到internet。我需要获得当前连接接口的IP地址,记住我的其他2个接口可能被分配了IP地址,只是没有连接 我可以通过我的每个接口ping一个网站,以确定哪个网站有连接,但我希望这比等待ping超时更快。我不想依赖外部网站 更新: 我的所有接口可能都有ip地址和网关。这是针对嵌入式设备的。因此,我们允许用户在eth0和eth1之间进行选择。但是,如果用户告诉我们使用的界面上没有连接,我们可以回过头来说eth2,这(理论上)总是有效的 因此

在我的linux机器上,3个网络接口中的1个可能实际连接到internet。我需要获得当前连接接口的IP地址,记住我的其他2个接口可能被分配了IP地址,只是没有连接

我可以通过我的每个接口ping一个网站,以确定哪个网站有连接,但我希望这比等待ping超时更快。我不想依赖外部网站

更新:

我的所有接口可能都有ip地址和网关。这是针对嵌入式设备的。因此,我们允许用户在
eth0
eth1
之间进行选择。但是,如果用户告诉我们使用的界面上没有连接,我们可以回过头来说
eth2
,这(理论上)总是有效的


因此,我需要做的是首先检查用户的选择是否已连接,如果已连接,则返回该IP。否则,我需要获取
eth2的ip
。我可以很好地获得接口的IP,这只是确定实际连接的是哪一个。

如果系统的默认网关是可靠的,那么从
路由-n
包含
“UG”
的行的输出中获取它(注意空格)还将包含网关的IP和活动接口的接口名称。

解决方案如下:


什么将界面归类为“关闭”?它不会有网关吗?它会有一个网关,但网关将无法访问吗?你真的不能仅仅通过查看IP来确定路由。多个接口可以路由到互联网(例如有线和无线)。它们中没有一个可以(直接)路由到internet,但在处理某些流量的路径中可能有代理。除非您使用ICMP、TCP/IP、UDP等与internet中的某个服务器建立连接,否则不存在到internet的连接。除非您与某个服务对话并得到答复,否则,你不能说你连接到了互联网。我认为你在这里使用的工具是错误的——如果你有三个互联网连接,传统上你会通过连接来解决这个问题,这样你最快的连接服务会首先请求,当它用完带宽时,你会溢出到你的另一个网络中接口。如果任何接口死亡,您将自动卸载到剩余的接口。如果你仔细阅读iptables/routing linux文档,你会发现比每隔几分钟测试一次更可靠的解决方案,如果你仍然在“运行”,这并不是我们正在做的。我们的eth2是一个ppp连接,只有在其他两个没有启动时才应该使用。有人投了反对票。。。如果他们愿意评论,这将有助于我理解我的错误!!!海报的问题更为抽象,您发布的代码特别是关于具有“链接”的接口的,正如海报所说,每个接口都可能具有链接,但可能无法连接到internet。

import fcntl
import array
import struct
import socket
import platform
"""
global constants.  If you don't like 'em here,
move 'em inside the function definition.
"""
SIOCGIFCONF = 0x8912
MAXBYTES = 8096

def localifs():
    """
    Used to get a list of the up interfaces and associated IP addresses
    on this machine (linux only).

    Returns:
    List of interface tuples.  Each tuple consists of
    (interface name, interface IP)
    """
    global SIOCGIFCONF
    global MAXBYTES

    arch = platform.architecture()[0]

    # I really don't know what to call these right now
    var1 = -1
    var2 = -1
    if arch == '32bit':
        var1 = 32
        var2 = 32
    elif arch == '64bit':
        var1 = 16
        var2 = 40
    else:
        raise OSError("Unknown architecture: %s" % arch)

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    names = array.array('B', '\0' * MAXBYTES)
    outbytes = struct.unpack('iL', fcntl.ioctl(
        sock.fileno(),
        SIOCGIFCONF,
        struct.pack('iL', MAXBYTES, names.buffer_info()[0])
        ))[0]

    namestr = names.tostring()
    return [(namestr[i:i+var1].split('\0', 1)[0], socket.inet_ntoa(namestr[i+20:i+24])) \
            for i in xrange(0, outbytes, var2)]


print localifs()