pychat/server.py

75 lines
2.2 KiB
Python
Raw Normal View History

2023-11-30 00:22:33 +01:00
import socket
import threading
2023-11-30 17:35:18 +01:00
HOST = '0.0.0.0'
2023-11-30 00:22:33 +01:00
PORT = 12345
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST, PORT))
clients = []
2023-11-30 17:35:18 +01:00
lock = threading.Lock()
2023-11-30 00:22:33 +01:00
2023-11-30 17:35:18 +01:00
def send_to_all(conn, msg):
with lock:
for client, _ in clients:
if client != conn:
try:
client.sendall(msg.encode('utf-8'))
except BrokenPipeError:
2023-12-01 14:34:20 +01:00
print("Verbindung verloren.")
with lock:
clients.remove((conn, nick))
conn.close()
break
2023-11-30 16:39:00 +01:00
2023-11-30 00:22:33 +01:00
def handle_client(conn, addr):
2023-11-30 16:39:00 +01:00
nick = conn.recv(1024).decode('utf-8')
print(f"Neuer Client verbunden: {addr} (Nickname: {nick})")
2023-11-30 17:35:18 +01:00
send_to_all(conn, f"{nick} hat den Chat betreten")
with lock:
clients.append((conn, nick))
2023-11-30 16:39:00 +01:00
2023-11-30 00:22:33 +01:00
while True:
try:
msg = conn.recv(1024).decode('utf-8')
if not msg:
break
2023-11-30 16:39:00 +01:00
elif msg == "exit":
print("Client getrennt:", addr)
2023-11-30 17:35:18 +01:00
send_to_all(conn, f"{nick} hat den Chat verlassen")
with lock:
clients.remove((conn, nick))
2023-11-30 16:39:00 +01:00
conn.close()
break
2023-11-30 00:22:33 +01:00
print(clients)
print(f"Nachricht von {addr}: {msg}")
2023-11-30 17:35:18 +01:00
2023-11-30 16:39:00 +01:00
if conn.fileno() != -1:
2023-11-30 17:35:18 +01:00
send_to_all(conn, f"<{nick}>:{msg}")
2023-11-30 16:39:00 +01:00
except ConnectionResetError:
print("Client getrennt (Verbindungsreset):", addr)
2023-11-30 17:35:18 +01:00
send_to_all(conn, f"{nick} hat den Chat verlassen")
with lock:
clients.remove((conn, nick))
2023-11-30 00:22:33 +01:00
conn.close()
break
def start_server():
server.listen()
print(f'Server läuft auf {HOST}:{PORT}')
while True:
conn, addr = server.accept()
threading.Thread(target=handle_client, args=(conn, addr)).start()
if __name__ == '__main__':
try:
start_server()
except KeyboardInterrupt:
print("Server wird heruntergefahren.")
2023-11-30 17:35:18 +01:00
with lock:
for client, nick in clients:
send_to_all(client, f"{nick} hat den Chat verlassen")
client.close()
2023-11-30 00:22:33 +01:00
server.close()