Python - 带套接字的多线程给出随机结果

Python - multithreading with sockets gives random results

我现在对我的问题真的很困惑。我想通过主机(或子网)列表发现一个开放端口。

所以首先让我们展示一下我到目前为止所做的事情..

from multiprocessing.dummy import Pool as ThreadPool 
from netaddr import IPNetwork as getAddrList
import socket, sys

this = sys.modules[__name__]

def threading(ip):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.settimeout(this.timeout)

    failCode = 0

    try:
        if sock.connect_ex((str(ip), this.port)) == 0:
            #port open
            this.count += 1
        else:
            #port closed/filtered
            failCode = 1
            pass
    except Exception: 
        #host unreachable
        failCode = 2
        pass
    finally:
        sock.close()

#set thread num
threads = 64
#set socket timeout
this.timeout = 1
#set ip list
ipList = getAddrList('8.8.8.0/24')
#set port
this.port = 53
#set count
this.count = 0

#threading
Pool = ThreadPool(threads) 
Pool.map_async(threading, ipList).get(9999999)
Pool.close()
Pool.join()

#result
print str(this.count)

脚本运行良好,没有任何错误。但是我正在为它打印出来的内容而苦苦挣扎..

因此,如果我想扫描子网 8.8.8.0/24 并发现端口 53。我知道唯一具有开放 dns 端口的服务器是 8.8.8.8 (google-dns).

但是当我 运行 我的脚本几次时 print str(this.count) 将随机(在我看来..) return 01 .

我还知道:

所以它似乎与导致我的计算机延迟的线程选项有关。但请注意,我的 CPU 使用率 <10%,网络使用率 <50%!

但是还有一点我不明白.. 如果 print str(this.count) returns 0 我通常会认为这是因为线程相互冲突并且套接字没有连接..但事实并非如此,因为如果 this.count 等于 0,则 failCode 设置为 1(在 8.8.8.8 上)!这意味着端口已关闭..但这一定也是我脚本的错误。我不认为这是由服务器延迟引起的..它是 google 没有延迟..

所以我们还知道:

所以我也在想,如果我有很多线程同时 运行 if sock.connect_ex((str(ip), this.port)) == 0: 可能主机 8.8.8.8 查找错误的答案值。也许它挣扎并查看 8.8.8.7 的响应。 ..希望你明白我的意思。

**max_socket_connections 在我的 linux 发行版中设置为 512

任何人都对套接字线程有经验,可以向我解释情况或给我一个如何防止这种情况的答案?

已解决:

..看答案..

第一个错误是:

But note that my CPU usage is <10% and the network usage is <50%!

实际上是 400% 的网络使用率。我期望位而不是字节。
好尴尬..

第二个错误是:

and we are sure the port is definitely open

Google 确实在短时间内尝试 ~5 次后实际上阻塞了端口。他们会在几秒或几分钟后解除限制。