使用Python檢測區域網路內IP地址使用方式

來源:互聯網
上載者:User

標籤:tip   als   name   add   工作   daemon   nim   roc   ip地址分配   

  在測試環境搭建的過程中,經常需要給伺服器分配靜態IP地址,由於不清楚當前區域網路內部哪些IP地址是閒置,所以經常需要一個一個的去試,才能找到一個可用的IP。在之前的一家公司工作的時候,用到過一個檢測IP使用方式的工具,但是屬於內部工具,無法擷取到。於是乎便想,何不自己開發一個呢?

  說做便做,開發環境使用的是Python3.6+PyQt5. 如果你的環境不一樣,可能會運行失敗。

  源碼地址:https://github.com/donglin-zhang/easyPing--python3.6

  1、介面設計

  介面用QtDesigner來畫的,先來一張原型圖如下,每次只能測試一個網段的IP佔用情況,0-255個小窗格用來顯示IP地址的使用方式,預設為灰色,程式執行後,IP地址已使用的顯示綠色,IP地址未被使用的顯示紅色。

  

  做介面的時候,255個小窗格畫起來實在是要人命,於是就僅畫出了視窗架構,將UI檔案轉成Python源碼後,自己手動編寫代碼來實現255窗格布局。程式碼片段如下:

     self.gridlayout = QtWidgets.QGridLayout(self.widget1)        self.gridlayout.setContentsMargins(0, 0, 0, 0)        self.gridlayout.setObjectName("gridlayout")        self.gridlayout.setSpacing(7)        self.label_list = []        list_index = 0        for i in range(1, 17):            for j in range(1, 17):                label = QtWidgets.QLabel(self.widget1)                label.setMinimumSize(QtCore.QSize(32, 15))                label.setStyleSheet("background-color: rgb(203, 203, 203);")                label.setAlignment(QtCore.Qt.AlignCenter)                label.setText(QtCore.QCoreApplication.translate("MyPing", str(list_index)))                self.label_list.append(label)                self.gridlayout.addWidget(label, i-1, j-1, 1, 1)                list_index += 1

 

  2、ping功能實現

  ping的實現方法有多種,最常用的當然是通過調用系統內建的ping功能來實現。

  Python來執行系統命令的方式有os.system(), os.popen(), subprocess等方法,在Python3.6的手冊中表明,subprocess模組是用來替代os.system等函數的。因此我們也使用subprocess模組來調用ping

  python3.5中,subprocess增加了一個run函數,run函數建立有一個子進程來運行需要執行的命令,返回一個CompletedProcess執行個體,該函數基本上可以處理所有的應用情境,run是對subprocess.Popen的一層封裝。

       python3.5以下可以使用subprocess.call(), subprocess.check_call()等函數來實現相同的功能,具體可查閱Python手冊

def get_ping_result(self, ip):    ‘‘‘    檢查對應的IP是否被佔用    ‘‘‘    cmd_str = "ping {0} -n 1 -w 600".format(ip)    DETACHED_PROCESS = 0x00000008   # 不建立cmd視窗    try:        subprocess.run(cmd_str, creationflags=DETACHED_PROCESS, check=True)  # 僅用於windows系統    except subprocess.CalledProcessError as err:        self._ping_signal.emit(False, ip)    else:        self._ping_signal.emit(True, ip)

    說明:

  在預設情況下,使用subprocess.run()執行ping命令的時候,會彈出一個cmd視窗,當256個線程一起啟動並執行時候,滿屏的視窗,想想都很酸爽。。。

       在windows系統下,可以傳入creationflags參數來使subprocess建立的子進程不產生console

  參考連結:https://stackoverflow.com/questions/7006238/how-do-i-hide-the-console-when-i-use-os-system-or-subprocess-call

  check參數為True時,函數將檢測執行結果是否為0(此處0表示執行成功),非零則拋出異常。

    3、多線程

        在使用pyqt進行GUI編程的時候,如果涉及到需要長時間後台啟動並執行操作,一般需要使用多線程的方式,否則介面會阻塞,直到後台運行結束,造成程式卡死的假象。

       在本程式實現,要實現256個地址的ping操作,如果單線程操作,肯定半天也無法得到結果,因此我們為每一個IP地址分配一個線程,最多256線程並發運行,1~2秒的時間即可得到整個網段的IP地址佔用情況

       多線程實現核心代碼如下:

def start_ping(self):    ‘‘‘    啟動多線程    ‘‘‘    self.reset_ui()    startip = self.ui.startIP.text().split(‘.‘)    endip = self.ui.endIP.text().split(‘.‘)    tmp_ip = startip    pthread_list = []    for i in range(int(startip[3]), int(endip[3]) + 1):        tmp_ip[3] = str(i)        ip = ‘.‘.join(tmp_ip)        pthread_list.append(threading.Thread(target=self.get_ping_result, args=(ip,)))    for item in pthread_list:        item.setDaemon(True)        item.start()

       

    子線程通過發射訊號的方式來通知主程式執行結果,最終主程式根據運行結果渲染介面。

    全部源碼可到GitHub下載,連結見文章頭部。


 

使用Python檢測區域網路內IP地址使用方式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.