このコード例は、「CPython Internals」の本に記載されています。
from queue import Queue
import socket
import time
timeout = 1.0
def check_port(host: str, port: int, results: Queue):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
result = sock.connect_ex((host, port))
if result == 0:
results.put(port)
sock.close()
if __name__ == '__main__':
start = time.time()
host = "localhost"
results = Queue()
for port in range(80, 100):
check_port(host, port, results)
while not results.empty():
print("Port {0} is open".format(results.get()))
print("Completed scan in {0} seconds".format(time.time() - start))
これにより、host == 'localhost'
このスクリプトは非常に高速に実行され(すべてのポート(1〜65535)は約1.5秒で確認されます!)、タイムアウト期間は何もしません。
ホストを「8.8.8.8」または他の外部ホストに設定すると、スクリプトの実行時間が正しく表示されます。たとえば、timeout == 1
8.8.8.8でポート440〜444を確認するのに約4秒かかります。
ローカルポートの可用性を確認するのはなぜそんなに速いのですか? (重要な場合はUbuntuを使用します)
私はこれが実際に必要ではないことを知っています。ローカルポートを確認するとき、なぜタイムアウト値がスクリプトの実行時間に影響しないのか疑問に思います。この質問は、プログラミングよりもオペレーティングシステムに関するものだと思うので、ここにあります。
答え1
localhostの場合、接続試行はすぐに拒否されるため、タイムアウトに達しません。リモートホストの場合、パケットを拒否するのではなく破棄するだけであるため(ファイアウォールとホストの設定によって異なります)、タイムアウトが発生します。