Моя реализация сервера:
Код: Выделить всё
import asyncio
import datetime as dt
import struct
import sys
from random import randrange
from zoneinfo import ZoneInfo
async def prepare_weather_data():
while True:
await asyncio.sleep(randrange(0, 7))
now = dt.datetime.now(ZoneInfo("Europe/Kyiv")).replace(microsecond=0).isoformat()
massage = f"{now} The temperature is {str(randrange(20, 30))} degrees Celsius"
message_encoded = massage.encode()
message_length = struct.pack('>I', len(message_encoded))
yield message_length + message_encoded
async def read_massage(reader: asyncio.StreamReader):
# Read the 4-byte length header
length_data = await reader.readexactly(4)
message_length = struct.unpack('>I', length_data)[0]
message_encoded = await reader.readexactly(message_length)
return message_encoded.decode()
async def handle_client(
_: asyncio.StreamReader,
writer: asyncio.StreamWriter,
weather_data: bytes,
):
try:
writer.write(weather_data)
await writer.drain()
except KeyboardInterrupt:
print("Closing the connection")
writer.close()
sys.exit(0)
async def main():
async def client_handler(reader, writer):
message = await read_massage(reader)
print(f"Received the message \"{message}\" that won't be handled any way")
async for weather_data in prepare_weather_data():
await handle_client(reader, writer, weather_data)
server = await asyncio.start_server(client_handler, "localhost", 8000)
async with server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())
Код: Выделить всё
import sys
import socket
import struct
def recvall(sock: socket.socket, n: int) -> bytes | None:
# Helper function to recv n bytes or return None if EOF is hit
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
def read_massage(sock: socket.socket) -> str | None:
# Read the 4-byte length
message_length_encoded = recvall(sock, 4)
if not message_length_encoded:
print("Socket closed")
sys.exit(0)
message_length = struct.unpack('>I', message_length_encoded)[0]
return recvall(sock, message_length).decode()
so = socket.socket(
socket.AF_INET,
socket.SOCK_STREAM,
)
so.connect(("localhost", 8000)) # Blocking
print("Connected")
try:
message = "Hello, give me a weather, please".encode()
# Pack the length of the message into 4 bytes (big-endian)
message_length = struct.pack('>I', len(message))
sent = so.send(message_length + message) # Blocking
print(f"Sent {sent} bytes")
while True:
msg = read_massage(so)
print(msg)
except KeyboardInterrupt:
so.close()
print("Socket closed")
sys.exit(0)
Подробнее здесь: https://stackoverflow.com/questions/790 ... -in-python