4

わかりましたので、接続できなかった場合に例外が発生すると考えて、次のことを行いました。

>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.settimeout(0.2)
>>> s.connect(("thisdomaiyndontexistduhh.com", 80))

しかし、例外は提起されませんでした。Python のソケット モジュールを使用してポートでサーバーが開いているかどうかをテストするにはどうすればよいですか? ありがとう!

4

2 に答える 2

16

上記のコードが失敗しない理由はここにあります。

私のISP(フロンティア)は、存在しないドメインに対して「198.105.251.114」を返すようにDNSを構成しています。そのため、実際には、そのアドレスのポート80でリッスンしているWebサーバーがあり、ガベージ/スパム検索結果を表示しています。DNSに8.8.8.8(Googleサーバー)を使用するようにホストを変更すると、上記のコードが機能する可能性があります。

この種の「キャプティブネットワーク」が一般的であることを考えると、コードが最初にすべきことは、そのようなネットワーク上にあるかどうかを判断することです。したがって、正しいことは、socket.gethostbyname( "thisdomaiyndontexistduhh.com")を呼び出すことです。実際に値が返される場合は、そのようなDNSサーバーの背後にいることがわかります。そのため、プローブするサーバーでgethostbyname呼び出しを実行します。同じDNSアドレスが返される場合は、サーバーが存在しないことがわかります。それ以外の場合は、接続呼び出しを続行してテストを終了します。

更新:私は休暇中にPythonを学んでいるので、この問題を練習の言い訳として使用しました。これが私のコードです:

import socket

def DoesServiceExist(host, port):
    captive_dns_addr = ""
    host_addr = ""

    try:
        captive_dns_addr = socket.gethostbyname("BlahThisDomaynDontExist22.com")
    except:
        pass

    try:
        host_addr = socket.gethostbyname(host)

        if (captive_dns_addr == host_addr):
            return False

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.settimeout(1)
        s.connect((host, port))
        s.close()
    except:
        return False

    return True
于 2013-01-02T07:19:52.233 に答える