我有一个python类,用于获取您所在本地计算机的IP地址。它适用于实际硬件(除非涉及桥接设备的MacOS)或本地VM。这是代码:
class IPAddress:
ip_address = None
def __init__(self):
return
def _get_interface_ip(self,ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s',
ifname[:15]))[20:24])
# does not work on MacOS with bridged devices such as vboxnet0, tap0, tun0
def get_lan_ip(self):
hostname = socket.gethostname()
ip = u''
try:
ip = socket.gethostbyname(hostname)
except socket.gaierror, e:
try:
ip = socket.gethostbyname(u'localhost')
except: pass
if ip.startswith("127.") and os.name != "nt":
interfaces = [
"eth0",
"eth1",
"eth2",
"en0",
"en1",
"en2",
"wlan0",
"wlan1",
"wifi0",
"ath0",
"ath1",
"ppp0",
]
for ifname in interfaces:
try:
ip = self._get_interface_ip(ifname)
break
except IOError:
pass
return ip
# Find out this instance
x = IPAddress()
server_ip = x.get_lan_ip()
除了AWS之外,它似乎无处不在。在AWS上,ifconfig eth0提供分配给eth0的内部IP地址,而该类提供与访问实例相关联的外部CNAME&#IP地址(在EC2 Classic中)。
是什么给出的?是否有更好的方法可以使用(例如)boto进行自我发现?
答案 0 :(得分:2)
首先,我不会使用gethostbyname()
或其亲属。这样做依赖于您无法控制的外部数据库,而这些数据库通常不是最新的。
接下来,我不会打电话给ioctl()
。任何特定的ioctl的存在,更不用说它的行为,在操作系统中都没有标准化。
如果是我,我会connect()
对某些外部服务,然后致电socket.getsockname()
:
def get_my_addr():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 53))
return s.getsockname()[0]
如果这不起作用,我会connect()
使用基于TCP的服务:
def get_my_addr():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('www.google.com', 80))
return s.getsockname()[0]