-
Notifications
You must be signed in to change notification settings - Fork 0
/
sockserver_mod.py
executable file
·84 lines (68 loc) · 2.77 KB
/
sockserver_mod.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
'''
sockserver_mod.py
TCP server using sockets and Python socketserver std module.
Protocol: depicted in naive_server.py
'''
__author__ = "Giulio Corradini"
import logging
import socket
import socketserver
import threading
import argparse
import sys
quitting_on_idle = threading.Event()
class CustomProtocolRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
buffer = bytearray()
try:
while True:
data = self.request.recv(1024)
if not data: break
buffer += data
command = buffer[:1].decode("ascii")
del buffer[:2]
response = self.commandDecoder(command[0])
self.request.sendall(response.encode('ascii'))
except ValueError as e:
logging.error("Client {} sent unknown command: {}".format(self.client_address, data))
self.request.sendall("Command not recognized")
except ConnectionResetError:
logging.info("Client {} disconnected".format(self.client_address))
def commandDecoder(self, command: str):
if command == '0':
return str(self.client_address)
elif command == '1':
return str(self.server)
elif command == '2':
return threading.current_thread().name
elif command == '3':
return str(threading.active_count())
elif command == '4':
return ', '.join(t.name for t in threading.enumerate())
elif command == 'q':
quitting_on_idle.set()
logging.info("Client {} asked to shutdown".format(self.client_address))
return "Quitting on idle"
else:
raise ValueError("Command not recognized.")
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
def main(host, port):
with ThreadedTCPServer((host, port), CustomProtocolRequestHandler) as server:
def checkForShutdown(): #closure
while True:
if quitting_on_idle.is_set():
server.shutdown()
break
t = threading.Thread(target=checkForShutdown, daemon=True, name="Shutdown_Check")
t.start()
logging.info("Started a threaded TCP server on {}:{}".format(host, port))
server.serve_forever()
logging.info("shutting down")
if __name__ == '__main__':
logging.basicConfig(format="%(asctime)s\t%(levelname)s\t%(threadName)s\t%(message)s", level=logging.INFO)
parser = argparse.ArgumentParser()
parser.add_argument("--address", "-a", default='', required=False, metavar="address")
parser.add_argument("--port", "-p", type=int, default=9999, required=False, metavar="port")
args = parser.parse_args(sys.argv[1:])
main(args.address, args.port)