简体   繁体   English

Python - 带套接字的多线程提供随机结果

[英]Python - multithreading with sockets gives random results

I am really confused about my problem right now. 我现在对我的问题感到很困惑。 I want to discover an open port over a list of hosts (or subnet). 我想在主机(或子网)列表上发现一个开放端口。

So first let's show what I've done so far.. 首先让我们展示一下到目前为止我所做的事情。

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)

The Script works fine without any error. 脚本工作正常,没有任何错误。 But I'm struggling about what it prints out.. 但我正在努力解决它打印出来的问题..

So if I want to scan for example the subnet 8.8.8.0/24 and discover port 53 . 因此,如果我想扫描例如子网8.8.8.0/24并发现端口53 I know the only server that has an open dns port is 8.8.8.8 (google-dns). 我知道唯一一个有开放式DNS端口的服务器是8.8.8.8 (google-dns)。

But when I run my script serveral times the print str(this.count) will randomly (as it seems to me..) return 0 or 1 . 但是当我运行我的脚本几次时, print str(this.count)将随机(在我看来......)返回01

What I also know: 我也知道:

  • Scan only 8.8.8.8 prints always 1 仅扫描8.8.8.8始终打印1
  • Use only 1 thread for /24 prints always 1 仅使用1个线程/24打印始终为1
  • Use 256 threads for /24 prints randomly 0 and 1 使用256个线程/24随机打印01
  • changing the timeout doesn't help 更改超时没有帮助

So it seems like it has to do with the threading option that causes lags on my computer. 所以它似乎与线程选项有关,导致我的计算机滞后。 But note that my CPU usage is <10% and the network usage is <50%! 但请注意我的CPU使用率<10%,网络使用率<50%!

But there is also another thing I don't understand.. If print str(this.count) returns 0 I would normally think it is because the threads are in conflict with each other and the socket doesn't get a connection.. but that isn't true because if this.count equals 0 , the failCode is set to 1 (on 8.8.8.8 )! 但还有另一件事我不明白..如果print str(this.count)返回0我通常会认为这是因为线程彼此冲突而套接字没有得到连接..但是这不是真的,因为如果this.count等于0 ,则failCode设置为1 (在8.8.8.8 )! Which means the port is closed.. but that must be also a bug of my script. 这意味着端口已关闭..但这也必须是我的脚本的错误。 I cannot think that this is caused by a lag of the server.. it's google there are no lags.. 我不能认为这是由服务器的延迟造成的..它的谷歌没有滞后..

So additionally we know: 另外我们知道:

  • output of 0 is because the server respond that the port is closed 输出0是因为服务器响应端口已关闭
  • and we are sure the port is definitely open 我们确信港口肯定是开放的

So I also think about that if I have many threads that run if sock.connect_ex((str(ip), this.port)) == 0: at the same time maybe the host 8.8.8.8 looks in the wrong answer value. 所以我也想到如果我有很多线程运行, if sock.connect_ex((str(ip), this.port)) == 0:同时主机8.8.8.8可能会查找错误的答案值。 Maybe it struggles and look in the response of 8.8.8.7 . 也许它在8.8.8.7的反应中挣扎和看。 ..hope you know what I mean. ..希望你知道我的意思。

**max_socket_connections is set to 512 on my linux distribution **我的linux发行版上的max_socket_connections设置为512

Anybody experienced with socket threading and can explain me the situation or give me an answer how to prevent this? 任何有套接字线程经验的人都可以向我解释一下情况,或者给我一个答案如何防止这种情况?

Solved: 解决了:

.. look at the answer .. ..看看答案..

The first mistake was: 第一个错误是:

But note that my CPU usage is <10% and the network usage is <50%! 但请注意我的CPU使用率<10%,网络使用率<50%!

Actually it was a 400 % network usage. 实际上它是400%的网络使用率。 I expected bits instead of bytes. 我期望比特而不是字节。
Very embrassing.. 非常尴尬..

And the second mistake was: 第二个错误是:

and we are sure the port is definitely open 我们确信港口肯定是开放的

Google does actually block the port after ~5 attempts in a short period of time. 谷歌确实在短时间内尝试了5次以后阻止该端口。 They release the restriction after a few seconds or minutes. 他们在几秒钟或几分钟后释放限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM