-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathServer.py
More file actions
150 lines (125 loc) · 4.96 KB
/
Server.py
File metadata and controls
150 lines (125 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import socket
import threading
import logging
import configparser
import os
import signal
import sys
from datetime import datetime
# Load configuration
config = configparser.ConfigParser()
config.read('server_config.ini')
HOST = config.get('SERVER', 'HOST', fallback='0.0.0.0')
PORT = int(config.get('SERVER', 'PORT', fallback='12345'))
MAX_CONNECTIONS = int(config.get('SERVER', 'MAX_CONNECTIONS', fallback='5'))
BUFFER_SIZE = int(config.get('SERVER', 'BUFFER_SIZE', fallback='1024'))
# Set up logging
logging.basicConfig(
filename='server.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# Also log to console
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
logging.getLogger().addHandler(console_handler)
# Global variable to control server shutdown
server_running = True
def signal_handler(sig, frame):
"""
Handle shutdown signals gracefully.
Args:
sig: Signal number
frame: Current stack frame
"""
global server_running
logging.info("Shutdown signal received. Stopping server...")
server_running = False
sys.exit(0)
def handle_client(client_socket, client_address):
"""
Handle individual client connections.
Args:
client_socket: Socket object for the client connection
client_address: Tuple containing client IP and port
"""
client_ip, client_port = client_address
logging.info(f"New client connected: {client_ip}:{client_port}")
try:
while server_running:
# Receive data from client
data = client_socket.recv(BUFFER_SIZE)
if not data:
logging.info(f"Client {client_ip}:{client_port} disconnected")
break
# Decode and log received data
message = data.decode('utf-8')
logging.info(f"Received from {client_ip}:{client_port}: {message}")
# Optional: Send acknowledgment back to client
try:
ack_message = f"Server received: {message}"
client_socket.sendall(ack_message.encode('utf-8'))
logging.debug(f"Sent acknowledgment to {client_ip}:{client_port}")
except Exception as e:
logging.error(f"Failed to send acknowledgment to {client_ip}:{client_port}: {e}")
except socket.error as e:
logging.error(f"Socket error with client {client_ip}:{client_port}: {e}")
except Exception as e:
logging.error(f"Unexpected error with client {client_ip}:{client_port}: {e}")
finally:
try:
client_socket.close()
logging.info(f"Closed connection to {client_ip}:{client_port}")
except Exception as e:
logging.error(f"Error closing connection to {client_ip}:{client_port}: {e}")
def start_server():
"""
Start the server and listen for client connections.
"""
global server_running
# Set up signal handlers for graceful shutdown
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
# Create server socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# Set socket options for better performance
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind to host and port
server.bind((HOST, PORT))
server.listen(MAX_CONNECTIONS)
logging.info(f"Server started successfully on {HOST}:{PORT}")
logging.info(f"Maximum connections: {MAX_CONNECTIONS}")
logging.info(f"Buffer size: {BUFFER_SIZE} bytes")
logging.info("Waiting for client connections...")
while server_running:
try:
# Accept client connection
client_socket, client_address = server.accept()
# Create thread for client handling
client_handler = threading.Thread(
target=handle_client,
args=(client_socket, client_address),
daemon=True
)
client_handler.start()
except socket.error as e:
if server_running:
logging.error(f"Error accepting connection: {e}")
break
except Exception as e:
logging.error(f"Server error: {e}")
finally:
try:
server.close()
logging.info("Server socket closed")
except Exception as e:
logging.error(f"Error closing server socket: {e}")
if __name__ == "__main__":
# Check if config file exists
if not os.path.exists('server_config.ini'):
logging.warning("Configuration file 'server_config.ini' not found. Using default values.")
start_server()