Python在Windows下获取本机IP
def get_ips_win():
from ctypes import Structure, windll, sizeof
from ctypes import POINTER, byref
from ctypes import c_ulong, c_uint, c_ubyte, c_char, c_uint64, c_void_p
time_t = c_uint64 if sizeof(c_void_p) == 8 else c_ulong
MAX_ADAPTER_DESCRIPTION_LENGTH = 128
MAX_ADAPTER_NAME_LENGTH = 256
MAX_ADAPTER_ADDRESS_LENGTH = 8
ERROR_BUFFER_OVERFLOW = 111
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", time_t),
("leaseExpires", time_t),
]
GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo
GetAdaptersInfo.restype = c_ulong
GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)]
buffer_size = c_ulong(1)
adapter_list = (IP_ADAPTER_INFO * 1)()
res = GetAdaptersInfo(byref(adapter_list[0]), byref(buffer_size))
if res == ERROR_BUFFER_OVERFLOW:
adapter_list = (IP_ADAPTER_INFO * buffer_size.value)()
res = GetAdaptersInfo(byref(adapter_list[0]), byref(buffer_size))
if res != 0:
return []
ips = []
for adapter in adapter_list:
name = adapter.description.decode('utf-8')
adapter_node = adapter.ipAddressList
while True:
ip_addr = adapter_node.ipAddress
if ip_addr:
ips.append((name, ip_addr.decode('utf-8')))
adapter_node = adapter_node.next
if not adapter_node:
break
return ips
def main():
for addr in get_ips_win():
print(addr)
if __name__ == '__main__':
main()
输出示例:
('ZeroTier Virtual Port', '192.168.196.37')
('Hyper-V Virtual Ethernet Adapter', '172.21.128.1')
('VMware Virtual Ethernet Adapter for VMnet1', '192.168.135.1')
('VMware Virtual Ethernet Adapter for VMnet8', '192.168.16.1')
('VirtualBox Host-Only Ethernet Adapter', '192.168.56.1')
('Hyper-V Virtual Ethernet Adapter #2', '192.168.1.154')