Skip to content

Instantly share code, notes, and snippets.

@iximiuz
Last active February 13, 2024 11:00
Show Gist options
  • Save iximiuz/c5f6c94838405798475162fc29808d09 to your computer and use it in GitHub Desktop.
Save iximiuz/c5f6c94838405798475162fc29808d09 to your computer and use it in GitHub Desktop.
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
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment