Python multithreading "ping" - python

I have been trying to make a python script that will ask you for a IP and have many simultaneous PING i shall do.
But it seems like i can only run one PING at a time
I'm running on OSX
import _thread
import os
import time
def main():
threadnbr = 0
ip = str(input("Input the ip adresse to play with? "))
threads = int(input("Have many threads? "))
check(ip)
if check(ip) == 0:
print("It is up")
else:
print("Is is down")
thread(ip, threads, threadnbr)
def thread(ip, threads, threadnbr):
while threads > threadnbr:
_thread.start_new_thread(dos(ip))
threadnbr = threadnbr + 1
else:
print(threadnbr, " started")
def check(ip):
response = os.system("ping -c 1 " + ip)
return response
def dos(ip):
os.system("ping -i 0.1 -s 8000 " + ip)
print("1")
main()

_thread.start_new_thread(dos(ip))
You are not providing the arguments correctly here - your code is running in the main thread. See the documentation for more details.
Also, you should be using threading instead of thread. That module is deprecated.
If dos means DoS, I sincerely hope you're doing this for educational purposes against your own infrastructure.

You could use the Scapy lib instead of using the builtin ping.
Here is a multithreaded ping with it:
import threading
from scapy.all import *
def send_pkt(dst,padding=0):
pkt = IP(dst=dst)/ICMP()/Padding('\x00'*padding)
ans,unans = sr(pkt)
ans.summary(lambda (s,r): r.sprintf("%IP.src% is alive"))
def thread(dst, threads, threadnbr):
while threads > threadnbr:
t = threading.Thread(None, send_pkt, None, (dst,), {'padding':8000})
t.start()
threadnbr = threadnbr + 1
else:
print(threadnbr, " started")
def main():
dst = raw_input("Input the ip adresse to play with? ")
threads = int(raw_input("Have many threads? "))
threadnbr = 0
send_pkt(dst)
thread(dst, threads, threadnbr)
main()

Related

How to write/read serial port with multithreading using pyserial

I'm currently running into a problem with trying to write to a serial device using pySerial. I want to be able to continuously update my terminal by reading the port and handle serial device writing on a seperate thread, meanwhile also be able to send a command via user input on the main thread. Everything runs as expected, except for that when I send one of the commands (cmdA or cmdB), the serial's output that I'm reading does not change (this is expected behaviour as the commands being sent alter the state of the device, which in turn changes the device's output that the serial port is reading). With all that said, it seems that the device is not receiving the command I am sending, even though the code continues to run with no exception and all functions seem to be executing as written.
Here is my current code:
A SerialMonitor class that can read the serial port and print out a specific amount of bytes once finding a set of "syncbytes"
# SerialMonitorTool.py
import threading
import time
import serial
class SerialMonitor(threading.Thread):
SYNC_BYTES = b'\x90\xeb'
def __init__(self, device='/dev/ttyUSB0', baudrate=115200, timeout=5):
print("Initializing Serial Monitor")
self._running = False
self._name = 'SerialMonitorThread-{}'.format(device)
self._device = serial.Serial(device, baudrate=baudrate, timeout=timeout)
self._write_lock = threading.Lock()
super().__init__(name=self._name)
def write(self, user_input, encode=False, terminator=None):
print("Locking for CMD Write...")
self._write_lock.acquire()
tx = user_input + terminator if terminator else user_input
print(f"Writing CMD to device: {tx}")
self._device.write(tx.encode() if encode else tx)
print("CMD Written...")
self._write_lock.release()
print("CMD Write Lock Released...")
def stop(self):
self._running = False
print('stop thread: ' + threading.current_thread().getName())
self.join()
def run(self):
print('starting thread: ' + threading.current_thread().getName())
self._running = True
try:
while self._running:
self._device.reset_input_buffer()
self._device.read_until(self.SYNC_BYTES)
ser_bytes = self._device.read(35)
print(f'\r{ser_bytes}', end='', flush=True)
time.sleep(0.25)
finally:
self._device.close()
and the main thread
# SerialMain.py
from SerialMonitorTool import *
cmdA = b'\x90\xeb\x01'
cmdB = b'\x90\xeb\x02'
monitor: SerialMonitor()
def print_help():
print('Usage: cmd [ a | b ]')
def send_cmd(cmd):
monitor.write(cmd)
def main():
monitor.start()
while True:
try:
user_input = input()
if user_input == '?' or user_input == 'h' or user_input == 'help':
print_help()
elif user_input == 'q' or user_input == 'quit':
break
elif user_input.startswith('cmd '):
cmd_type = user_input[len('cmd '):].split(' ')
if cmd_type[0] == 'a':
send_cmd(cmdA)
elif cmd_type[0] == 'b':
send_cmd(cmdB)
except Exception as e:
print(e)
monitor.stop()
def process_args():
# process arguments
import argparse
parser = argparse.ArgumentParser(description='Serial Test Tool')
parser.add_argument(
'-D', '--device',
help='Use the specified serial device.',
default='/dev/ttyUSB0',
type=str
)
global monitor
monitor = SerialMonitor()
if __name__ == "__main__":
process_args()
main()
It looks like there is issue in your write method, try to comment all the lock related code in write method or put lock syntax in below sequence.
def write(self, user_input, encode=False, terminator=None):
tx = user_input + terminator if terminator else user_input
print(f"Writing CMD to device: {tx}")
self._device.write(tx.encode() if encode else tx)
print("CMD Written...")
print("Locking for CMD Write...")
self._write_lock.acquire()
self._write_lock.release()
print("CMD Write Lock Released...")

Threading program doesn't quit

I am writing a program which constantly checks if certain IP adresses are connected to the network. If they are, nothing happens. If they are not connected for a certain time, an action is triggered.
My script works as intended as far as I can tell, however when I try to exit it using ctrl+c it simply doesnt stop.
I guess it has something to do with the threading that I am using, but I cant figure out what exactly it is.
This is my code so far:
import os
import time
from threading import Timer, Thread
import json
with open("ip_adresses.json", "r") as f:
ip_adresses_dict = json.load(f)
def timeout():
print("ACTION IS TRIGGERED")
# dummy Timer thread
print("dummy timer created")
t = Timer(999999999, timeout)
t.daemon = True
try:
while True:
ip_adress_reachable = []
for key, value in ip_adresses_dict.items():
if os.system(f"ping -c 1 -W 1 {value} > /dev/null") is 0: # this means its reachable
ip_adress_reachable.append(True)
else:
ip_adress_reachable.append(False)
print(ip_adress_reachable)
# if no ip adresses are reachable and no timer running, start a timer.
if any(ip_adress_reachable) == False and t.is_alive() == False:
print("starting a new thread")
t = Timer(15, timeout)
t.daemon = True
t.start()
# If in the meantime ip adress gets reachable cancel the timer.
elif any(ip_adress_reachable) == True and t.is_alive() == True:
# cancel the timer
print("timer was canceled")
t.cancel()
except KeyboardInterrupt:
print("quitting")
t.join(1)
I am kinda lost, because I though that deamon threads would stop after the main loop is done (i.e. after I press ctr+c)
If somebody could help me out, I would be very grateful.
After testing I found that all problem makes os.system() which catchs Ctrl+C to stop process running in os.system() - ping - and it doesn't send this information to Python.
If you run ping longer and you skip /dev/null
os.system(f"ping -c 5 -W 1 {value}")
then you will see that Ctrl+C stops ping
If I uses subprocess then I don't have this problem.
subprocess.call(f"ping -c 1 -W 1 {value} > /dev/null", shell=True)
Code which I used for test on Linux Mint 20 (based on Ubuntu 20.04)
#import os
import time
from threading import Timer, Thread
#import json
import subprocess
#with open("ip_adresses.json", "r") as f:
# ip_adresses_dict = json.load(f)
ip_adresses_dict = {
'x': '192.168.0.1',
'y': '192.168.0.2',
'z': '192.168.0.3',
}
def timeout():
print("ACTION IS TRIGGERED")
# dummy Timer thread
print("dummy timer created")
t = Timer(999999999, timeout)
t.daemon = True
try:
while True:
ip_adress_reachable = []
for key, value in ip_adresses_dict.items():
print('[DEBUG] start process')
#result = os.system(f"ping -c 1 -W 1 {value} > /dev/null")
#result = os.system(f"ping -c 5 -W 1 {value}")
result = subprocess.call(f"ping -c 1 -W 1 {value} > /dev/null", shell=True)
print('[DEBUG] end process')
ip_adress_reachable.append( result == 0 )
print(ip_adress_reachable)
# if no ip adresses are reachable and no timer running, start a timer.
if any(ip_adress_reachable) is False and t.is_alive() is False:
print("starting a new thread")
t = Timer(15, timeout)
t.daemon = True
t.start()
# If in the meantime ip adress gets reachable cancel the timer.
elif any(ip_adress_reachable) is True and t.is_alive() is True:
# cancel the timer
print("timer was canceled")
t.cancel()
except KeyboardInterrupt:
print("quitting")
if t.is_alive():
t.join(1)
Doc: Replacing os.system()

raw_input with Main thread and concurrent thread in Python

I am working on a Python scripts that kicks off a thread with a loop and a raw_input so that user can enter commands. After this thread starts, main program starts a loop with another raw_input so that the user can enter commands.
How can this be organized so that the commands being inputted via console goes to the correct raw_input (main thread/concurrent thread)? At the moment, all inputs in the console are going to the main thread only.
Thanks
Example
import threading
def commThread():
while True:
chatAcceptance = raw_input("User")
t1 = threading.Thread(target=commThread)
t1.start()
while True:
userInput = raw_input("\nPlease insert a command:\n")
So this can be done via lock. I did a small code example that shows how to swap between one "scope" to the other using the raw_input.
import threading
lock = threading.Lock()
def inputReader(thread, prompt):
userInput = raw_input(prompt)
print thread + " " + userInput + "\n"
return userInput
def myThread1():
global lock
while True:
lock.acquire()
print "thread 1 got the lock\n"
while True:
threadInput = inputReader("thread 1", "from thread 1\n")
if threadInput == "release":
lock.release()
print "thread 1 released the lock\n"
break
def myThread2():
global lock
while True:
lock.acquire()
print "thread 2 got the lock\n"
while True:
threadInput = inputReader("thread 2", "from thread 2\n")
if threadInput == "release":
lock.release()
print "thread 2 released the lock\n"
break
t1 = threading.Thread(target=myThread1).start()
t2 = threading.Thread(target=myThread2).start()

How would I export my results to a .txt

I have the following code running and I would like to have the output of the script exported to a .txt file for later viewing. How could I go about doing this?
import socket, threading
def TCP_connect(ip, port_number, delay, output):
TCPsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
TCPsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
TCPsock.settimeout(delay)
try:
TCPsock.connect((ip, port_number))
output[port_number] = 'Listening'
except:
output[port_number] = ''
def scan_ports(host_ip, delay):
threads = [] # To run TCP_connect concurrently
output = {} # For printing purposes
# Spawning threads to scan ports
for i in range(10000):
t = threading.Thread(target=TCP_connect, args=(host_ip, i, delay, output))
threads.append(t)
# Starting threads
for i in range(10000):
threads[i].start()
# Locking the script until all threads complete
for i in range(10000):
threads[i].join()
# Printing listening ports from small to large
for i in range(10000):
if output[i] == 'Listening':
print(str(i) + ': ' + output[i])
def main():
host_ip = input("Enter host IP: ")
delay = int(input("How many seconds the socket is going to wait until timeout: "))
scan_ports(host_ip, delay)
if __name__ == "__main__":
main()
print ("Thank you for scanning")
Any help would be greatly appreciated.
with open("your_desired_txt_filename", "a") as myFile:
Then, at the part where you want to write to the file:
myFile.write(your_content) ## Indent this line with the suitable level of indentation (it will be at least one indentation level deeper than the `with` clause

Python can't communicate with subprocess of a Minecraft server

I'm trying to write a handler/controller for the Minecraft server. My problem is that I can't seem get writing and reading to work properly. When a client issues a command that uses the server class's method serverCom, the Minecraft server's text/log starts to come into the Python window/Python console and the connected client hangs. Also, it seems that after I use Popen, the Minecraft server doesn't really launch until I do write to the server (aka serverCom method). In case anyone is wondering, the Popen goes to a batch file that opens the .jar file. This is on Windows XP.
import subprocess
import os
import configobj
import socket
import threading
from time import sleep
config = configobj.ConfigObj("config.ini")
cHost = config["hostip"]
cPort = int(config["hostport"])
cBuffer = int(config["serverbuffer"])
cClients = int(config["numberofclients"])
cPassword = config["password"]
class server(object):
def __init__(self):
self.process = False
self.folder = "C:\\servers\\minecraft-danny"
self.max = configobj.ConfigObj("%s\\simpleserver.properties"%self.folder)["maxPlayers"]
def serverStart(self):
if not self.process:
self.process = subprocess.Popen("java -Xmx1024m -Xms1024m -jar minecraft_server.jar nogui", cBuffer, None, subprocess.PIPE, subprocess.PIPE, subprocess.STDOUT, cwd = self.folder)
return True
return False
def serverStop(self):
if self.process:
self.serverCom("stop")
self.process = False
return True
return False
def serverCom(self, text):
if self.process:
self.process.stdout.seek(2)
self.process.stdin.write("%s\n"%text)
self.process.stdin.flush()
self.process.stdout.flush()
return (str(self.process.stdout.readline()), True)
return ("", False)
def serverPlayers(self):
if self.process:
self.serverCom("list")
x = self.serverCom(" ")[0].split(":")[3].replace("\n","").replace(" ","")
if x == "":
x = 0
else:
x = len(x.split(","))
return (x, self.max)
return (0,self.max)
serv = server()
def client(cnct, adr):
global count
try:
dat = str(cnct.recv(cBuffer)).split(" ")
ans = False
if dat[0] == "start":
print "Client %s:%s started the MC Server....."%(adr[0], adr[1])
x = serv.serverStart()
sleep(1)
serv.serverCom(" ")
serv.serverCom(" ")
sleep(5)
if x:
ans = "Server is now online."
else:
ans = "Server is already online."
elif dat[0] == "stop":
print "Client %s:%s stopped the MC Server....."%(adr[0], adr[1])
x = serv.serverStop()
sleep(6)
if x:
ans = "Server is now offline."
else:
ans = "Server is already offline."
elif dat[0] == "commun":
print "Client %s:%s executed a command on the MC Server....."%(adr[0], adr[1])
serv.serverCom(" ".join(dat[1:]))
x = serv.serverCom(" ")
if x[1]:
ans = x[0]
else:
ans = "No return text, server is offline or not responding."
elif dat[0] == "players":
print "Client %s:%s recieved the player count from the MC Server....."%(adr[0], adr[1])
pc = serv.serverPlayers()
ans = "%s/%s"%(pc[0],pc[1])
elif dat[0] == "help":
print "Client %s:%s recieved the help list....."%(adr[0], adr[1])
ans = "__________\nstart - Starts the server.\nstop - Stops the server.\ncommun <command> - Writes to server's console.\nplayers - Returns player count.\nhelp - Shows this help.\nclose - Closes client connections.\n__________"
elif dat[0] == "close":
pass
else:
ans = "Command '%s' is not valid."%dat[0]
if ans:
cnct.send("PASS")
cnct.send("%s\n"%ans)
threading.Thread(target = client, args = (cnct, adr,)).start()
else:
cnct.send("DICN")
cnct.send("Connection to server closed.\n")
cnct.close()
print "Client %s:%s disconnected....."%(adr[0], adr[1])
if count:
count -= 1
except:
cnct.close()
print "Client %s:%s disconnected..... "%(adr[0], adr[1])
if count:
count -= 1
print "-MC Server Control Server v0.0.1 BETA-"
print "Starting up server....."
print "Connecting to socket....."
count = 0
sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sck.bind((cHost, cPort))
sck.listen(5)
print "Connected and listening on %s:%s....."%(cHost, cPort)
print "Setting up client listener, allowing %s clients to connect at a time....."%cClients
while True:
for x in range(cClients):
(cnct, adr) = sck.accept()
print "Client %s:%s connected....."%(adr[0], adr[1])
cnct.send("Welcome to MineCraft Server Control.\n\nPlease enter server control password.\n")
ps = str(cnct.recv(cBuffer))
if count < cClients:
if ps == cPassword:
cnct.send("CRRT")
cnct.send("%s was correct.\nIf you need help type 'help'."%ps)
count += 1
threading.Thread(target = client, args = (cnct, adr,)).start()
else:
cnct.send("WRNG")
cnct.send("%s wasn't the correct password, please try again."%ps)
cnct.close()
print "Client %s:%s rejected....."%(adr[0], adr[1])
else:
cnct.send("WRNG")
cnct.send("Too many clients connected to MineCraft Server Control")
cnct.close()
print "Client %s:%s rejected....."%(adr[0], adr[1])
sck.close()
I have no idea how a Minecraft server works, but there are a number of problems with your code:
You are redirecting stderr to stdout from the created Java process, then expecting a line response from the server. This could be the reason that the Minecraft server is not starting, since it would block on a stderr write (depending on how Windows XP handles it). Additionally, any stderr write (e.g. log write) will destroy any structured responses you may be waiting for.
You are reading with sock.recv(N) and then assuming that you get the whole chunk (e.g. password). This is not how TCP works, you may very well get just one character back (especially true if the user types the password interactively e.g. in a Telnet prompt).
You are flushing the stdout of the subprocess, which is your input stream. You probably want to flush the stdin of the subprocess. Flushing an input stream makes no sense, it is the output stream that determines when to flush.

Categories