python获取本机局域网ip地址(Windows)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jaket5219999/article/details/84140019

Talk is cheap, show the code: (win10+python3.7在wifi和热点环境下亲测可用)

#!/usr/bin/env python3
import os
import platform
import re


class PlatformUnsupportedError(Exception):
    pass


def get_local_ip():
    """获取本机的局域网ip地址,仅适用于Windows系统"""
    if platform.system() != "Windows":
        raise PlatformUnsupportedError(
            "Platform not supported! Only for windows."
        )
    ips = local_ips()
    if not ips:
        raise Exception("Error: Fail to get ip!")
    # print(ips, [IP2MAC(ip).mac for ip in ips])
    if len(ips) > 1:
        # 当通过热点连接,且热点中有多个连接时
        # 会返回多个ip值,可通过获取MAC地址的方式来过滤它们
        # 若过滤完不是唯一值,则抛出异常
        ips_with_mac = [ip for ip in ips if IP2MAC(ip).mac]
        if not len(ips_with_mac) == 1:
            raise Exception(
                "Got multiple IP addresses: {}".format(", ".join(ips))
            )
        return ips_with_mac[0]
    return ips[0]


def local_ips():
    ips = []
    for ip in getIPAddresses():
        ip = ip.decode()
        if ip[-1] not in "01":
            ips.append(ip)
    return ips


class IP2MAC:
    RE_MAC = re.compile("([a-f0-9]{2}[-:]){5}[a-f0-9]{2}", re.I)

    def __init__(self, ip):
        self.__ip = ip

    @property
    def mac(self):
        with os.popen("arp -a {}".format(self.__ip)) as osp:
            macaddr = self.RE_MAC.search(osp.read())
        return macaddr.group() if macaddr else None


def getIPAddresses():
    # This function was got from the following url:
    # https://www.cnblogs.com/whu-2017/p/8986842.html
    #
    # It just work for windows.
    from ctypes import Structure, windll, sizeof
    from ctypes import POINTER, byref
    from ctypes import c_ulong, c_uint, c_ubyte, c_char

    MAX_ADAPTER_DESCRIPTION_LENGTH = 128
    MAX_ADAPTER_NAME_LENGTH = 256
    MAX_ADAPTER_ADDRESS_LENGTH = 8

    class IP_ADDR_STRING(Structure):
        pass

    LP_IP_ADDR_STRING = POINTER(IP_ADDR_STRING)
    IP_ADDR_STRING._fields_ = [
        ("next", LP_IP_ADDR_STRING),
        ("ipAddress", c_char * 16),
        ("ipMask", c_char * 16),
        ("context", c_ulong),
    ]

    class IP_ADAPTER_INFO(Structure):
        pass

    LP_IP_ADAPTER_INFO = POINTER(IP_ADAPTER_INFO)
    IP_ADAPTER_INFO._fields_ = [
        ("next", LP_IP_ADAPTER_INFO),
        ("comboIndex", c_ulong),
        ("adapterName", c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
        ("description", c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
        ("addressLength", c_uint),
        ("address", c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
        ("index", c_ulong),
        ("type", c_uint),
        ("dhcpEnabled", c_uint),
        ("currentIpAddress", LP_IP_ADDR_STRING),
        ("ipAddressList", IP_ADDR_STRING),
        ("gatewayList", IP_ADDR_STRING),
        ("dhcpServer", IP_ADDR_STRING),
        ("haveWins", c_uint),
        ("primaryWinsServer", IP_ADDR_STRING),
        ("secondaryWinsServer", IP_ADDR_STRING),
        ("leaseObtained", c_ulong),
        ("leaseExpires", c_ulong),
    ]
    GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo
    GetAdaptersInfo.restype = c_ulong
    GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)]
    adapterList = (IP_ADAPTER_INFO * 10)()
    buflen = c_ulong(sizeof(adapterList))
    rc = GetAdaptersInfo(byref(adapterList[0]), byref(buflen))
    if rc == 0:
        for a in adapterList:
            adNode = a.ipAddressList
            while True:
                ipAddr = adNode.ipAddress
                if ipAddr:
                    yield ipAddr
                adNode = adNode.next
                if not adNode:
                    break


def main():
    print("Local ip of this computer:")
    print(get_local_ip())


if __name__ == "__main__":
    main()

运行结果:

Local ip of this computer:
192.168.2.123
 

猜你喜欢

转载自blog.csdn.net/jaket5219999/article/details/84140019