diff --git a/client-threaded.py b/client-threaded.py new file mode 100644 index 0000000..5ca90f0 --- /dev/null +++ b/client-threaded.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 +import sys + +oldexcepthook = sys.excepthook +def newexcepthook(type,value,traceback): + oldexcepthook(type,value,traceback) + #input("Press ENTER to quit.") +sys.excepthook = newexcepthook + +import os +p = os.path.join +pUp = os.path.dirname +s = False +if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'): + s = os.path.realpath(sys.executable) +else: + s = os.path.realpath(__file__) +sp = pUp(s) + +# script start +import subprocess +import socket +import threading +import queue + +def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) + +bufferSize = 8096 # buffer size in bytes +timeout = 15 # timeout in seconds +connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + +unbufferedStdout = os.fdopen(sys.stdout.fileno(),"wb",0) # Make unbuffered stdout + +q = queue.Queue() + +class stdoutThread(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + + def run(self): + while True: + data = q.get() + try: + while True: + data += q.get(False) + except Queue.Empty: + pass + unbufferedStdout.write(data) + +class sendThread(threading.Thread): + def __init__(self,connection): + threading.Thread.__init__(self) + + def run(self): + while True: + data = q.get() + try: + while True: + data += q.get(False) + except Queue.Empty: + pass + connection.sendall(data) + +def listToCommand(lst): + cmd = "" + for arg in lst: + arg = arg.replace("\\","\\\\") + arg = arg.replace(",","\\,") + cmd += arg + "," + + return cmd[:-1] + +def commandToList(cmd): + args = [] + cArg = "" + escape = False + for letter in cmd: + if escape == True: + cArg += letter + escape = False + continue + + if letter == "\\": + escape = True + continue + + if letter == ",": + if cArg == "": continue + args.append(cArg) + cArg = "" + continue + + cArg += letter + + args.append(cArg) + + return args + +def makePayload(lst): + cmdText = listToCommand(lst) + cmdBytes = cmdText.encode("utf-8") + cmdBytes += b" " * (1024 - len(cmdBytes)) + return cmdBytes + +def stringToAddressTuple(addr): + rtn = addr.rsplit(":",1) + rtn[1] = int(rtn[1]) + rtn = tuple(rtn) + return rtn + +def main(): + global serverAddr + serverAddr = stringToAddressTuple(sys.argv[1]) + global bufferSize + + eprint("Connecting to server...") + connection.settimeout(timeout) + connection.connect(serverAddr) + eprint("Sending payload...") + connection.sendall(makePayload(sys.argv[2:])) + eprint("Receiving payload...") + args = commandToList(connection.recv(1024).decode("utf-8").rstrip(" ")) + if sys.argv[2] == "watch": + bufferSize = int(args[0]) + try: + thr = stdoutThread() + thr.start() + eprint("Receiving data...") + while True: + data = connection.recv(bufferSize) + if data == b"": return + q.put(data) + except: + connection.close() + raise + + if sys.argv[2] == "broadcast": + bufferSize = int(sys.argv[3]) + try: + eprint("Sending data...") + while True: + data = sys.stdin.buffer.read(bufferSize) + connection.sendall(data) + except: + connection.close() + raise + +if __name__ == '__main__': + main()