python 获取自身ip

Posted 笔记本

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 获取自身ip相关的知识,希望对你有一定的参考价值。

原文

见过很多获取服务器本地IP的代码,个人觉得都不是很好,例如以下这些

不推荐:靠猜测去获取本地IP方法

  

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import fcntl
import struct
 

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
                                        s.fileno(),
                                        0x8915, # SIOCGIFADDR
                                        struct.pack(256s, ifname[:15])
                                        )[20:24])


print "br1 = "+ get_ip_address(br1)
print "lo = " + get_ip_address(lo)
print "virbr0 = " + get_ip_address(virbr0)

 

这类代码带有猜测的行为。

如果机器上只有eth0 或者 只有bond0上有IP,那么此类代码都有可能失败,而且还不容易移植到其他平台上。

不推荐:通过hostname来获取本机IP

import socket
print(socket.gethostbyname(socket.gethostname())) 
# 有可能出现这个情况 
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
socket.gaierror: [Errno -2] Name or service not known

这个方法是通过获取hostname,然后再通过hostname反查处机器的IP。这个方法也是不推荐的。因为很多的机器没有规范这个hostname的设置。

另外就是有些服务器会在 /etc/hosts 中添加本机的hostname的地址,这个做法也不是不可以,但是如果设置成了 127.0.0.1,那么获取出来的IP就都是这个地址了。

通过 UDP 获取本机 IP,目前见过最优雅的方法

这个方法是目前见过最优雅获取本机服务器的IP方法了。没有任何的依赖,也没有去猜测机器上的网络设备信息。

而且是利用 UDP 协议来实现的,生成一个UDP包,把自己的 IP 放如到 UDP 协议头中,然后从UDP包中获取本机的IP。

这个方法并不会真实的向外部发包,所以用抓包工具是看不到的。但是会申请一个 UDP 的端口,所以如果经常调用也会比较耗时的,这里如果需要可以将查询到的IP给缓存起来,性能可以获得很大提升。

注意: 上面的方法需要网卡配置网关(错误网关也可)

# 在 shell 中可以一行调用,获取到本机IP
python -c "import socket;print([(s.connect((‘8.8.8.8‘, 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])"

 

# 可以封装成函数,方便 Python 的程序调用
import socket

def get_host_ip(): 
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect((‘8.8.8.8‘, 80))
        ip = s.getsockname()[0]
    finally:
        s.close()
    return ip

 

以上是关于python 获取自身ip的主要内容,如果未能解决你的问题,请参考以下文章

常用python日期日志获取内容循环的代码片段

Unity Android获取自身IP地址

scrapy按顺序启动多个爬虫代码片段(python3)

delphi 获取自身句柄

wcf客户端怎么获取自身使用的端口号?

VC获取自身窗口句柄