TCP Chat Room with Telnet Proxy: Build Your Own Distributed Messaging System

💡 Fun Fact: The first chat system (Talkomatic) was created in 1973 at the University of Illinois - modern TCP chat rooms use similar concepts but with encryption and proxy capabilities!

TCP Chat System Architecture

Core Components

1. Chat Server

Handles client connections, message routing, and room management using TCP sockets

2. Telnet Proxy

Legacy interface allowing telnet clients to connect to modern chat systems

3. Client Apps

Native/GUI clients and terminal-based interfaces

TCP Chat Server Implementation (Python)

# chat_server.py import socket import threading from collections import defaultdict class ChatServer: def __init__(self, host='0.0.0.0', port=5555): self.clients = defaultdict(dict) # {room: {client_socket: username}} self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.server_socket.bind((host, port)) self.server_socket.listen(5) print(f"🚀 Server listening on {host}:{port}") def broadcast(self, message, room, sender_socket=None): """Send message to all clients in a room""" for client in self.clients[room]: if client != sender_socket: # Don't echo to sender try: client.send(message.encode('utf-8')) except: self.remove_client(client, room) def handle_client(self, client_socket, room): """Manage individual client connections""" username = client_socket.recv(1024).decode('utf-8') self.clients[room][client_socket] = username self.broadcast(f"🌟 {username} joined the room!", room) while True: try: message = client_socket.recv(1024).decode('utf-8') if not message: break formatted_msg = f"{username}: {message}" self.broadcast(formatted_msg, room, client_socket) except: break self.remove_client(client_socket, room) def remove_client(self, client_socket, room): """Clean up disconnected clients""" if client_socket in self.clients[room]: username = self.clients[room][client_socket] del self.clients[room][client_socket] self.broadcast(f"👋 {username} left the room", room) client_socket.close() def run(self): """Main server loop""" while True: client_socket, addr = self.server_socket.accept() room = client_socket.recv(1024).decode('utf-8') # First message is room name threading.Thread( target=self.handle_client, args=(client_socket, room) ).start() if __name__ == "__main__": server = ChatServer() server.run()

Telnet Proxy Gateway

# telnet_proxy.py import socket import threading import re class TelnetProxy: def __init__(self, chat_host='localhost', chat_port=5555, proxy_port=2323): self.chat_host = chat_host self.chat_port = chat_port self.proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.proxy_socket.bind(('0.0.0.0', proxy_port)) self.proxy_socket.listen(5) print(f"🔌 Telnet proxy running on port {proxy_port}") def translate_telnet(self, telnet_socket): """Convert telnet raw commands to chat protocol""" # Connect to real chat server chat_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) chat_socket.connect((self.chat_host, self.chat_port)) # Telnet negotiation stripping telnet_socket.send(b"Welcome to Telnet Chat Proxy!\r\n") telnet_socket.send(b"Enter room name: ") room = telnet_socket.recv(1024).decode('ascii').strip() chat_socket.send(room.encode('utf-8')) telnet_socket.send(b"Enter username: ") username = telnet_socket.recv(1024).decode('ascii').strip() chat_socket.send(username.encode('utf-8')) # Bidirectional forwarding while True: try: # Telnet -> Chat Server telnet_data = telnet_socket.recv(1024) if not telnet_data: break clean_data = re.sub(rb'\xFF[\xFB\xFC\xFD\xFE].', b'', telnet_data) # Strip telnet commands chat_socket.send(clean_data.strip()) # Chat Server -> Telnet chat_data = chat_socket.recv(1024) if not chat_data: break telnet_socket.send(chat_data + b'\r\n') except: break telnet_socket.close() chat_socket.close() def run(self): while True: client, addr = self.proxy_socket.accept() print(f"Telnet connection from {addr}") threading.Thread(target=self.translate_telnet, args=(client,)).start()

Key Features

Feature Implementation Security Consideration
Multi-room Support Dictionary mapping rooms to client lists Limit rooms per IP to prevent abuse
Telnet Compatibility Command stripping and CRLF conversion Sanitize telnet control sequences
Message Broadcasting Selective echo to room members Rate limiting per client
Connection Handling Thread-per-client model Max connections limit

Advanced Enhancements

🔒 TLS Encryption

Wrap sockets with SSLContext for secure communication:

context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)

🌐 WebSocket Gateway

Add browser support with WebSocket-to-TCP bridge:

async def websocket_handler(ws):
  tcp_socket = connect_to_chat_server()

📊 Message Persistence

Store chat history in SQLite:

INSERT INTO messages VALUES (?,?,?,datetime('now'))

⚠️ Security Checklist

  • Implement message size limits (prevent DoS)
  • Add authentication for sensitive rooms
  • Log all connection attempts
  • Use non-blocking sockets for production
  • Consider switching to asyncio for scale

Testing Your Chat System

Terminal Client

$ nc localhost 5555
general
Alice
Hello world!
^C

Telnet Session

$ telnet localhost 2323
Welcome to Telnet Chat Proxy!
Enter room name: general
Enter username: Bob
Hi Alice!
Connection closed

*

Posting Komentar (0)
Lebih baru Lebih lama