Essentially we want to replicate ``` nmap -p 4000-4100 hostname ``` Source: [this gist](https://gist.github.com/betrcode/0248f0fda894013382d7) For this particular use of `nmap`, I have this Python script, which outputs JSON (so avoids the need to parse the output of nmap). It runs each attempt to connect in a separate thread, each with a 1 second timeout, which is fine for a LAN. ```py #!/usr/bin/env python3 import json import sys import socket from threading import Thread def isOpen(ip,port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.settimeout(1.0) s.connect((ip, int(port))) s.shutdown(socket.SHUT_RDWR) s.close() return True except Exception as e: return False class Pinger: def __init__(self,host,baseport=7000,count=100): self.host = host self.baseport = baseport self.count = count self.targets = set(range(count)) self.openports = set() self.threads = [] self.ports = set() for n in self.targets: thread = Thread(target=self.task,args=(n,)) self.threads.append(thread) def task(self,n): targets = self.targets ports = self.ports if n in targets: targets.remove(n) port = n + self.baseport if isOpen(self.host,port): ports.add(n) def start(self): for thread in self.threads: thread.start() def join(self): for thread in self.threads: thread.join() def result(self): return (self.host,list(sorted(self.ports))) hosts = sys.argv[1:] pingers = [] for host in hosts: pingers.append((host,Pinger(host))) for host, pinger in pingers: pinger.start() for host, pinger in pingers: pinger.join() data = {} for host, pinger in pingers: _, ports = pinger.result() data[host] = ports j = json.dumps(data) print(j) ```