为什么使用python套接字的端口扫描在Windows上比在linux上慢得多?

时间:2017-09-19 01:35:22

标签: python linux windows sockets security

我尝试通过不同的python文档,论坛和其他人的问题在线浏览,但我还没有找到任何有同样问题的人。

我的脚本通常是什么样的,我将创建一个尝试连接到端口1-9999的套接字连接,并且只会在端口打开时告诉我。当我在Windows上运行它时,需要1秒才能扫描一个端口,然后再转到下一个端口(60个端口/ m .~16.5m用于1000个端口)。当我在linux上运行相同的脚本时,它会非常快速地遍历所有9999个端口,同时仍然返回相同的期望结果。

我希望能够构建交叉兼容的工具,但它似乎是linux  在我的网络需求方面,它是更好的操作系统吗?我可以随意使用,所以我不介意使用其中一个。我想知道是否可以采取任何措施使端口扫描在两个操作系统上几乎同样快速,否则我不会花太多时间在Windows上构建。

无论我在哪个网络上,速度的差异都是相同的。

我的问题是:
•当给出相同的功能时,为什么Windows上的性能与linux相比有如此不同?
•是否有任何可以做的事情来使端口扫描更快地像套接字一样在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上。

2 个答案:

答案 0 :(得分:0)

Windows限制了半开连接的并发数量,如果您一次打开多个连接请求,则可以在此处使用。例如,在Windows 7上尝试将此键值设置为0(以禁用它) HKEY_LOCAL_MACHINE \ SYSTEM \ CURRENTCONTROLSET \服务\ TCPIP \参数\ EnableConnectionRateLimiting

答案 1 :(得分:0)

我怀疑这会导致性能问题,但是,scan_host()功能存在错误。

此函数尝试返回r_code,但r_code仅在connect_ex()返回0时设置。如果connect_ex()返回非零值,或者在同一代码块中发生异常,则不会设置r_code,并且return语句将引发{{1}异常。此异常将传播到调用代码,然后捕获它并忽略它和所有其他异常。

忽略异常并不是一个好主意;也许你可能会学到与问题相关的东西,也许不会,但我建议你记录正在发生的异常。

此外,如果您在代码中添加了一些调试打印语句,那将非常有用。这将帮助您找到代码中花费大部分时间的部分。

还有一句话:

NameError

似乎永远不会被执行 - 我无法说明,因为你帖子中的缩进可能不太正确。

另一件需要考虑的事情是DNS。可能Windows使用的DNS服务器速度较慢,或者存在一些问题。您可以通过使用IP地址而不是主机名来消除它:

hostip = gethostbyname(host)