日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Python 獲取本機 IP 地址

系統 1898 0

前言

引出問題:

在參考網上獲取 IP 地址的代碼,具體實現如下:

            
              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,
        struct.pack('256s', ifname[:15]))[20:24])

get_ip_address('eth0')

            
          

由于使用的是 Window 系統,所以不可避免的出現了錯誤,報錯如下:

            
               from fcntl import ioctl
ImportError: No module named fcntl

            
          

網上搜索相關解決方法,因為 Python 缺少對應的 fcntl 模塊,這個模塊是 Python 自帶的,但 Windows 好像沒有。由于代碼實現比較簡單,網上就給了該模塊的實現代碼,如下:

            
              def fcntl(fd, op, arg=0):
    return 0
 
def ioctl(fd, op, arg=0, mutable_flag=True):
    if mutable_flag:
        return 0
    else:
        return ""
 
def flock(fd, op):
    return
 
def lockf(fd, operation, length=0, start=0, whence=0):
	return

            
          

將該部分代碼保存為 fcntl.py,并存放在 Python 的安裝目錄下,類似于: D:\Soft_Install\Python37\Lib 。

終于不再報上述的錯誤后,但是獲取 IP 仍然存在問題。

            
              	struct.pack('256s', IFNAME[:15])
struct.error: argument for 's' must be a bytes object

            
          

修改成如下模式: struct.pack(b'256s', ifname[:15].encode("utf-8")) ,再次執行,得到如下結果:

            
              TypeError: 'int' object is not subscriptable

            
          

究其原因,是因為 fcntl.ioctl(s.fileno(),0x8915,struct.pack(b'256s', ifname[:15].encode("utf-8"))) 返回結果為 0。

網上再次搜索了很久,都沒有找到合適的解決方案,因此決定換個方式實現獲取 IP 地址。

分析

IP 獲取

通過 Python 代碼實現 IP 地址獲取,首先需要在本機上找到需要獲取的 IP 地址。獲取 IP 的手段簡單分為兩種,分別在百度搜 ip 查詢,查詢到本機的 public ip 如第一張圖,再利用 ipconfig 查詢到自身 ip 如第二張圖。我們能看到這兩個地址是不同的,那么不是說,每個主機都只有一個 ip 地址么,為什么我們查到的兩個 Ip 地址不一樣呢。

Python 獲取本機 IP 地址_第1張圖片
Python 獲取本機 IP 地址_第2張圖片
詳細講解可自行前往 IP 講解進行學習,這里只總結一下:

            
              ipconfig 查出來的是你本機的 IP 地址,也就是內網私有地址,此類地址僅在局域網使用,不能聯通外網。
百度查出來的地址是你上網的共有地址,也許并不是你主機的地址,而是電信或聯通分給你的地址,用于連接互聯網。

            
          

Python 代碼實現

一、Windows 上實現

            
              import os
import socket

def get_window_ip1():
    """
    查詢本機ip地址
    :return: ip
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        print(s.getsockname())
        ip = s.getsockname()[0]
    finally:
        s.close()

    return ip

def get_window_ip2():
    # 獲取本機計算機名稱
    hostname = socket.gethostname()
    # 需要注意的是,如果本機有多網卡,比如說安裝的有虛擬機,則此ip可能是虛擬機VMnet8的ip,而你真正的內網IP可能是物理無線適配器wlan的IP
    ip = socket.gethostbyname(hostname)

    #這種情況下,首先需要獲取所有網卡的ip地址,然后人為進行篩選
    ipList = socket.gethostbyname_ex(hostname)
    return ipList[2][-1]

def get_window_ip3():
    return [a for a in os.popen('route print').readlines() if ' 0.0.0.0 ' in a][0].split()[-2]

def get_window_ip4():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(('baidu.com', 0))
    ipaddr = s.getsockname()[0]
    return ipaddr

            
          

二、Linux 上實現

1、

            
              def get_ip_address():
    # 獲取本機計算機名稱
    hostname = socket.gethostname()
    ip = socket.gethostbyname(hostname)

    #下面這兩種種方法同樣可以
    # fqdnName = socket.getfqdn(socket.gethostname())
    # ip = socket.gethostbyname(fqdnName)

	# s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # s.connect(('baidu.com', 0))
    # ip = s.getsockname()[0]
    return ip

            
          

同在 Windows 上使用,上述方法在 Linux 下也可以獲取到正確的 IP 地址。

2、

            
              import socket
import fcntl
import struct

IFNAME = 'eth0'

def get_ip_address(ifname=IFNAME):
    '''獲取網卡的ip地址'''
    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])

            
          

如果遇到報錯 IOError: [Errno 19] No such device ,說明當前 Linux 系統沒有 eth0 網卡。在之前的博客 Centos7 使用 yum 命令遇到的問題總結一文中,為了聯網修改網卡配置文件,當時修改的是叫做 ens33 的網卡,可以通過 ip addr 命令查看當前系統的網卡信息。在驗證 IP 獲取代碼的過程中,將“enth0”改為“ens33”,即可獲取正確 IP 信息。如果想要將 ens33 網卡改為 eth0 網卡,可以參考 CentOS7沒有eth0網卡一文進行修改。

3、

            
              def get_ip_address():
    # Use ip route list
    import subprocess
    arg = 'ip route list'
    p = subprocess.Popen(arg, shell=True, stdout=subprocess.PIPE)
    data = p.communicate()
    sdata = data[0].split()
    ipaddr = sdata[sdata.index('src') + 1]  #ip
    netdev = sdata[sdata.index('dev') + 1]  #網卡信息
    return (ipaddr, netdev)

            
          

更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 海南省| 黄骅市| 叙永县| 平陆县| 大厂| 古交市| 乌拉特后旗| 鱼台县| 梁河县| 黎平县| 鄄城县| 霸州市| 重庆市| 东海县| 维西| 固始县| 科技| 孟津县| 杂多县| 上高县| 察隅县| 扶余县| 嘉禾县| 兴海县| 喀喇沁旗| 郎溪县| 九龙县| 宽甸| 瑞安市| 信阳市| 南丰县| 襄汾县| 无锡市| 明溪县| 新昌县| 门源| 陵水| 临泽县| 九龙县| 常州市| 澄城县|