2 questions:
- I'm missing something
- Is there any other way to implement this?
Did I miss something
I think it is worth checking the error codes here:
if code == 0: return True else: return False
considering you are trying to start a pool ! 10K all kinds of errors may occur, i.e. Reach some restrictions on the system / your users (check ulimit -a ), and you will consider such errors as a closed port without notification. This may explain the erratic results that you experience.
By the way, on my MacBook, the results are consistent (check on my live server on VPS hosting)
Id also selects fewer threads - 10K is an excess. For example, here are the default values ββsuggested in python docs :
Changed in version 3.5: If max_workers is missing or not set, it will default to the number of processors on the machine multiplied by 5, assuming that ThreadPoolExecutor is often used to overlap I / O of the CPU, and the number of workers should be higher than the number of workers for ProcessPoolExecutor
Is there any other way to implement this?
First of all, there is no need to use threads/processes - non-blocking sockets + event multiplexers , for example epoll exist for many years, so you can leave without additional threads / processed things.
The connect / close method is also suboptimal because you just need to check if the port is open or not - you do not need a full TCP connection here.
In the simplest case, you just need to send the SYN segment and verify that the server will respond.
Heres a good article with dozens of methods using scapy
Scapy is a powerful interactive batch processing program. it is an opportunity to fake or decode packets from a large number of protocols, send them on a wire, capture them, respond to requests and answers, and much more. It can easily handle most of the classic tasks like scanning, tracing, probing, unit tests, attacks or network discovery (this can replace hping, 85% nmap, arpspoof, arp-sk, arping, tcpdump, tethereal, p0f, etc. d.).
Here is one of the method descriptions ("TCP connect scan"):
The client sends the first handshake using the SYN flag and the port to connect to the server in the TCP packet. If the server responds with RST instead of SYN-ACK, then this port closes to the Server
And another method ("Scan TCP Stack"):
This method is similar to checking the TCP connection. The client sends a TCP packet with the SYN flag set and the port number to connect to. If the port is open, the server responds with the SYN and ACK flags inside the TCP packet. But this time, the client sends the RST flag to TCP, not RST + ACK, which was the case with the TCP scan connection. This method is used to prevent port scan detection through firewalls.
Of course, if you just want to play with sockets / streams, your approach will also be fine even without pcap / scapy