Skip to content

Instantly share code, notes, and snippets.

@iximiuz iximiuz/serv_async.py
Last active Nov 22, 2019

Embed
What would you like to do?
Python Web Servers
# python3
import asyncio
import sys
counter = 0
async def run_server(host, port):
server = await asyncio.start_server(serve_client, host, port)
await server.serve_forever()
async def serve_client(reader, writer):
global counter
cid = counter
counter += 1
print(f'Client #{cid} connected')
request = await read_request(reader)
if request is None:
print(f'Client #{cid} unexpectedly disconnected')
else:
response = await handle_request(request)
await write_response(writer, response, cid)
async def read_request(reader, delimiter=b'!'):
request = bytearray()
while True:
chunk = await reader.read(4)
if not chunk:
# Клиент преждевременно отключился.
break
request += chunk
if delimiter in request:
return request
return None
async def handle_request(request):
await asyncio.sleep(5)
return request[::-1]
async def write_response(writer, response, cid):
writer.write(response)
await writer.drain()
writer.close()
print(f'Client #{cid} has been served')
if __name__ == '__main__':
asyncio.run(run_server('127.0.0.1', int(sys.argv[1])))
# python3
import os
import socket
import sys
import time
def run_server(port=53210):
serv_sock = create_serv_sock(port)
active_children = set()
cid = 0
while True:
client_sock = accept_client_conn(serv_sock, cid)
child_pid = serve_client(client_sock, cid)
active_children.add(child_pid)
reap_children(active_children)
cid += 1
def serve_client(client_sock, cid):
child_pid = os.fork()
if child_pid:
# Родительский процесс, не делаем ничего
client_sock.close()
return child_pid
# Дочерний процесс:
# - читаем запрос
# - обрабатываем
# - записываем ответ
# - закрываем сокет
# - завершаем процесс (os._exit())
request = read_request(client_sock)
if request is None:
print(f'Client #{cid} unexpectedly disconnected')
else:
response = handle_request(request)
write_response(client_sock, response, cid)
os._exit(0)
def reap_children(active_children):
for child_pid in active_children.copy():
child_pid, _ = os.waitpid(child_pid, os.WNOHANG)
if child_pid:
active_children.discard(child_pid)
def create_serv_sock(serv_port):
serv_sock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM,
proto=0)
serv_sock.bind(('', serv_port))
serv_sock.listen()
return serv_sock
def accept_client_conn(serv_sock, cid):
client_sock, client_addr = serv_sock.accept()
print(f'Client #{cid} connected '
f'{client_addr[0]}:{client_addr[1]}')
return client_sock
def read_request(client_sock, delimiter=b'!'):
request = bytearray()
try:
while True:
chunk = client_sock.recv(4)
if not chunk:
# Клиент преждевременно отключился.
return None
request += chunk
if delimiter in request:
return request
except ConnectionResetError:
# Соединение было неожиданно разорвано.
return None
except:
raise
def handle_request(request):
time.sleep(5)
return request[::-1]
def write_response(client_sock, response, cid):
client_sock.sendall(response)
client_sock.close()
print(f'Client #{cid} has been served')
if __name__ == '__main__':
run_server(port=int(sys.argv[1]))
# python3
import socket
import sys
import time
def run_server(port=53210):
serv_sock = create_serv_sock(port)
cid = 0
while True:
client_sock = accept_client_conn(serv_sock, cid)
serve_client(client_sock, cid)
cid += 1
def serve_client(client_sock, cid):
request = read_request(client_sock)
if request is None:
print(f'Client #{cid} unexpectedly disconnected')
else:
response = handle_request(request)
write_response(client_sock, response, cid)
def create_serv_sock(serv_port):
serv_sock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM,
proto=0)
serv_sock.bind(('', serv_port))
serv_sock.listen()
return serv_sock
def accept_client_conn(serv_sock, cid):
client_sock, client_addr = serv_sock.accept()
print(f'Client #{cid} connected '
f'{client_addr[0]}:{client_addr[1]}')
return client_sock
def read_request(client_sock, delimiter=b'!'):
request = bytearray()
try:
while True:
chunk = client_sock.recv(4)
if not chunk:
# Клиент преждевременно отключился.
return None
request += chunk
if delimiter in request:
return request
except ConnectionResetError:
# Соединение было неожиданно разорвано.
return None
except:
raise
def handle_request(request):
time.sleep(5)
return request[::-1]
def write_response(client_sock, response, cid):
client_sock.sendall(response)
client_sock.close()
print(f'Client #{cid} has been served')
if __name__ == '__main__':
run_server(port=int(sys.argv[1]))
# python3
import socket
import sys
import time
import threading
def run_server(port=53210):
serv_sock = create_serv_sock(port)
cid = 0
while True:
client_sock = accept_client_conn(serv_sock, cid)
t = threading.Thread(target=serve_client,
args=(client_sock, cid))
t.start()
cid += 1
def serve_client(client_sock, cid):
request = read_request(client_sock)
if request is None:
print(f'Client #{cid} unexpectedly disconnected')
else:
response = handle_request(request)
write_response(client_sock, response, cid)
def create_serv_sock(serv_port):
serv_sock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM,
proto=0)
serv_sock.bind(('', serv_port))
serv_sock.listen()
return serv_sock
def accept_client_conn(serv_sock, cid):
client_sock, client_addr = serv_sock.accept()
print(f'Client #{cid} connected '
f'{client_addr[0]}:{client_addr[1]}')
return client_sock
def read_request(client_sock, delimiter=b'!'):
request = bytearray()
try:
while True:
chunk = client_sock.recv(4)
if not chunk:
# Клиент преждевременно отключился.
return None
request += chunk
if delimiter in request:
return request
except ConnectionResetError:
# Соединение было неожиданно разорвано.
return None
except:
raise
def handle_request(request):
time.sleep(5)
return request[::-1]
def write_response(client_sock, response, cid):
client_sock.sendall(response)
client_sock.close()
print(f'Client #{cid} has been served')
if __name__ == '__main__':
run_server(port=int(sys.argv[1]))
@AstraSerg

This comment has been minimized.

Copy link

AstraSerg commented Nov 22, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.