Skip to content

Commit 7b07abb

Browse files
committed
Asyncio server
1 parent f6aaa31 commit 7b07abb

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import argparse
2+
import logging
3+
import threading
4+
import asyncio
5+
6+
"""
7+
Connect to this server using netcat or similar utilities
8+
"""
9+
10+
HOST, PORT = "127.0.0.1", 9999
11+
12+
def handle_command(cmd: str, client_stream: asyncio.StreamWriter):
13+
if not cmd: return
14+
if cmd == '0':
15+
return f"Client address: {client_stream.get_extra_info('peername')}\n"
16+
elif cmd == '1':
17+
return f"Socket address: {client_stream.get_extra_info('sockname')}\n"
18+
elif cmd == '2':
19+
return f"Current thread name: {threading.current_thread().getName()}\n"
20+
elif cmd == '3':
21+
return f"Alive threads number: {threading.active_count()}\n"
22+
elif cmd == '4':
23+
return f"Alive threads: {[t.getName() for t in threading.enumerate()]}\n"
24+
else: # Help
25+
return """'0': Return the remote address (client) to which the socket is connected;
26+
'1': Return the server socket's own address;
27+
'2': Return the current thread name;
28+
'3': Return the number of alive threads;
29+
'4': Return the list of names of alive threads (comma separated);
30+
'q': Quit server when all the clients will be disconnected;
31+
"""
32+
33+
async def server_handler(reader, writer):
34+
addr = writer.get_extra_info('peername')
35+
logging.info(f"Serving {addr}")
36+
while True:
37+
writer.write(">> ".encode())
38+
await writer.drain()
39+
data = await reader.read(1024)
40+
cmd = data.decode().strip()
41+
42+
logging.info(f"Received {cmd} from {addr}")
43+
44+
if not cmd:
45+
writer.close()
46+
break
47+
elif cmd == 'q':
48+
logging.warning(f"Closed connection: {addr}")
49+
writer.close()
50+
break
51+
else:
52+
writer.write(handle_command(cmd, writer).encode())
53+
await writer.drain()
54+
55+
async def main():
56+
global HOST, PORT
57+
logging.basicConfig(level=logging.DEBUG, format="%(threadName)s --> %(asctime)s - %(levelname)s: %(message)s",
58+
datefmt="%H:%M:%S")
59+
parser = argparse.ArgumentParser()
60+
parser.add_argument("-a", "--address", help="host address", default=HOST, type=str, dest="address")
61+
parser.add_argument("-p", "--port", help="port number", default=PORT, type=int, dest="port")
62+
args = parser.parse_args()
63+
PORT = args.port
64+
HOST = args.address
65+
66+
logging.info(f"Server running on {HOST}:{PORT}...")
67+
68+
server = await asyncio.start_server(server_handler, HOST, PORT)
69+
70+
71+
try:
72+
async with server:
73+
await server.serve_forever()
74+
except KeyboardInterrupt:
75+
logging.warning("Server stopping...")
76+
77+
78+
79+
if __name__ == "__main__":
80+
asyncio.run(main())

OtherSocketExamples/multithreaded_simple_server.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020

2121
def client_handle(conn, addr):
22-
logging.info(f"New connection {addr}".encode())
22+
logging.info(f"New connection {addr}")
2323
while True:
2424
conn.sendall(">> ".encode())
2525
data = conn.recv(1024).decode() # command

0 commit comments

Comments
 (0)