好的,所以我做了以下工作,认为如果它无法连接会引发异常:
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.settimeout(0.2)
>>> s.connect(("thisdomaiyndontexistduhh.com", 80))
但没有例外。如何在使用Python的套接字模块的端口上测试服务器是否打开?谢谢!
答案 0 :(得分:15)
以上代码永远不会失败。
我的ISP(Frontier)配置DNS,以便对于任何不存在的域,它将返回“198.105.251.114”。因此,他们实际上有一个Web服务器在该地址的端口80上侦听以显示一些垃圾/垃圾邮件搜索结果。将您的主机更改为使用8.8.8.8(Google服务器)进行DNS,您上面的代码可能会有效。
鉴于这些“强制网络”很常见,您的代码应该做的第一件事就是确定它是否在这样的网络上。因此,正确的做法是调用socket.gethostbyname(“thisdomaiyndontexistduhh.com”)。如果它实际返回一个值,那么你知道你是这样一个DNS服务器的幕后推手。这样,然后在要探测的服务器上执行gethostbyname调用。如果它返回相同的DNS地址,则表示服务器不存在。否则,继续进行connect调用以完成测试。
更新:我在假期一直在学习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
答案 1 :(得分:0)
我发现此解决方案使用telnetlib
和urllib
来测试网址之间的服务器之间的连接,例如“ https://example.com:6789/test”,在这种情况下,首先寻找端口,然后寻找架构。我只考虑“ http”和“ https”,但是添加或更改架构(sftp,ssh等)很容易。
import telnetlib
import time
from urllib.parse import urlsplit
def verify_service(endpoint):
netloc = "{0.netloc}".format(urlsplit(endpoint))
scheme = "{0.scheme}".format(urlsplit(endpoint))
if netloc == '':
return False
p = netloc.split(":")
if len(p) == 2:
host = p[0]
port = p[1]
else:
host = p[0]
port = 80 if scheme == "http" else "443"
try:
tn = telnetlib.Telnet(host,port)
time.sleep(1)
except:
return False
return True