Ressenger/ressenger_server.py

66 lines
2.1 KiB
Python
Executable File

#!/usr/bin/python3
import socket
import threading
import struct
import time
import sys
HOST = '0.0.0.0'
def recv_exact(conn, n):
"""Keep reading until exactly n bytes are received, or return None on EOF"""
buf = bytearray()
while len(buf) < n:
chunk = conn.recv(n - len(buf))
if not chunk:
return None
buf.extend(chunk)
return bytes(buf)
def handle_client(conn, addr):
print(f'Connected: {addr}')
try:
while True:
header = recv_exact(conn, 4)
if header is None:
print(f'Client {addr} disconnected')
break
length = struct.unpack('!I', header)[0] # Network byte order (big-endian)
if length == 0:
# Optional: length 0 means heartbeat or empty message
print(f'Received an empty message from {addr}')
continue
data = recv_exact(conn, length)
if data is None:
print(f'Client {addr} disconnected prematurely while reading data')
break
# Handle binary data here (may take time)
print(f'Received {len(data)} bytes of data from {addr}')
print(data)
# Simulate time-consuming processing (replace with real logic)
# time.sleep(1) # Even if you have long tasks, other connections are still accepted
except Exception as e:
print(f'Exception occurred while handling client {addr}: {e}')
finally:
conn.close()
print(f'Closed connection {addr}')
def run_server(PORT):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((HOST, PORT))
sock.listen()
print(f'Server listening on {HOST}:{PORT}...')
try:
while True:
conn, addr = sock.accept()
t = threading.Thread(target=handle_client, args=(conn, addr), daemon=True)
t.start()
except KeyboardInterrupt:
print('Server shutting down...')
finally:
sock.close()
if __name__ == '__main__':
run_server(int(sys.argv[1]))