2017-09-19 65 views
0

我試過在網上搜索不同的python文檔,論壇和其他人的問題,但我還沒有找到任何人有這個相同的問題。爲什麼Windows上的python套接字掃描比在linux上慢很多?

我的腳本的典型樣子是我將創建一個套接字連接,嘗試連接到1-9999端口,並且只會在端口打開時告訴我。當我在Windows上運行它時,在移動到下一個端口之前需要1秒鐘的時間才能掃描一個端口(每個端口60個端口/米〜16.5米)。當我在linux上運行相同的腳本時,它將非常快速地遍歷所有9999端口,同時仍然返回相同的期望結果。

我一直希望能夠構建交叉兼容的工具,但是看起來linux 只是在我的網絡需求方面更好的操作系統?我有兩個在我的處置,所以我不介意使用一個在另一個。我只想知道是否有任何可以使端口掃描在兩個操作系統上都同樣快的操作,否則我不會花費太多的時間在Windows上進行構建。

無論我在哪個網絡,速度的差異都是一樣的。

我的問題是:
•爲什麼在給定相同函數的情況下,與Windows相比,windows的性能如此不同?
•有沒有什麼辦法可以像使用linux一樣快速地使用套接字掃描端口?

- 編輯 -

這裏的一塊,我用它來檢查端口

def whole_scan(Host_): 
    service = '' 
    host = Host_ 
    max_port = 9999 
    min_port = 1 
    def scan_host(host, port, r_code = 1): 
     try: 
      s = socket(AF_INET, SOCK_STREAM) 
      code = s.connect_ex((host, port)) 
      if code == 0: 
       r_code = code 
       s.close() 
     except Exception, e: 
      pass 
     return r_code 
     hostip = gethostbyname(host) 
    for port in range(min_port, max_port): 
     try: 
      response = scan_host(host,port) 
      if response == 0: 
       try: 
        service = getservbyport(port) 
       except Exception, e: 
        service = 'n/a' 
      print(" |--port: %d\t%s" % (port,service.upper())) 
     except Exception, e: 
      pass 

我也驗證了我的防火牆被禁用,並且增加價值到我的註冊表來禁用連接上的限制表現沒有變化。我在Windows 10上。

+0

由於UNIX是專爲網絡和網絡是專爲UNIX,任何品牌的UNIX,包括基於Linux的系統,可以說是在選擇時更有優勢網絡平臺。這就是說,這裏可能還有別的東西在工作。你的窗口盒子是否啓用了防火牆?它可以阻止通知(未過濾)封閉端口的RST,ACK分組。 – spectras

+0

@spectras我的筆記本電腦上的AV是禁用的,netsh advfirewall顯示allprofiles顯示所有防火牆都關閉。我想認爲必須有一些東西,但是我很難找到它 – saniboy

+0

你能提供一個簡化的,自包含的基準測試和兩個操作系統的數字嗎?有很多方法可以進行端口掃描(阻塞vs非阻塞,並行vs順序,連接vs syn),所以最好有一個具體的例子加上實際的數字。 –

回答

0

Windows限制了半打開連接的併發數量,如果您一次打開多個連接請求,可能會在這裏發揮作用。例如,在Windows 7上嘗試將此鍵值設置爲0(以禁用它) HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters \ EnableConnectionRateLimiting

+0

我看了一下,雖然該條目在win X上不存在,我曾看到一篇文章說,如果8號已經不存在,那麼可能會創建同樣的東西,所以我嘗試了它,但不幸的是沒有任何區別。 – saniboy

0

我懷疑這是導致性能問題,但是,您的scan_host()函數中存在一個錯誤。

此函數嘗試返回r_code,但是,僅在connect_ex()返回0時纔會設置r_codeconnect_ex()應該返回一個非零值,或者在同一代碼塊中發生異常,則不會設置r_code,並且return語句會引發異常。這個異常將傳播到調用代碼,然後捕獲它並忽略它和所有其他異常。

忽略異常並不是一個好主意;也許你可能會學到與問題相關的東西,也許不會,但我建議你記錄正在發生的異常。

另外,如果您在代碼中添加了一些調試打印語句,它會很有用。這將幫助您找到大部分時間花費在代碼中的部分。

還有行:

hostip = gethostbyname(host) 

這似乎從來沒有被執行 - 我不能說,因爲也許在您的文章壓痕是不完全正確。

要考慮的另一件事是DNS。 Windows使用的DNS服務器可能較慢,或者存在一些問題。您可以消除通過使用IP地址而不是主機名:

response = scan_host(gethostbyname(host), port) 
+0

我認爲這不是問題。我做了一些類似的事情,但是使用tcp客戶端嘗試使用socket.connect(主機,端口)連接到一系列端口,並且在linux上運行速度很快,但在Windows上運行速度慢。我很感激你指出,雖然!當我回家後,我會在代碼中更改它 – saniboy

+1

通過檢查例外情況,您可能會得到一些線索。同樣,添加帶時間戳的調試語句也可能有所幫助。我還用其他一些建議更新了我的答案。 – mhawke

+0

另外,hostip在代碼的這一部分沒有提供任何用途,但是DNS聽起來很有趣,而且不是我曾經考慮過的。我假設Windows和Linux使用的是相同的DNS服務器,因爲我從未指定過哪一個我想讓他們使用。 – saniboy

相關問題