import socket, select #Function to broadcast chat messages to all connected clients def broadcast (server_socket, sock, message): for socket in CONNECTION_LIST: if socket != server_socket and socket != sock : #Do not send the message to master socket and the client who has send us the message try : socket.send(message) except : # broken socket connection may be, chat client pressed ctrl+c for example socket.close() CONNECTION_LIST.remove(socket) if __name__ == "__main__": # List to keep track of socket descriptors CONNECTION_LIST = [] RECV_BUFFER = 4096 # Advisable to keep it as an exponent of 2 PORT = 5000 # you can change the port if you want USERNAMES = {} #new data structure server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # this has no effect, why ? server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind(("0.0.0.0", PORT)) server_socket.listen(10) # Add server socket to the list of readable connections CONNECTION_LIST.append(server_socket) print "Your chat server started on port " + str(PORT) print """ /$$ |__/ /$$$$$$$ /$$$$$$ /$$$$$$ /$$ /$$ /$$ /$$$$$$$ /$$$$$$ /$$_____/ /$$__ $$ /$$__ $$| $$ /$$/| $$| $$__ $$ /$$__ $$ | $$$$$$ | $$$$$$$$| $$ \__/ \ $$/$$/ | $$| $$ \ $$| $$ \ $$ \____ $$| $$_____/| $$ \ $$$/ | $$| $$ | $$| $$ | $$ /$$$$$$$/| $$$$$$$| $$ \ $/ | $$| $$ | $$| $$$$$$$ |_______/ \_______/|__/ \_/ |__/|__/ |__/ \____ $$ /$$ \ $$ | $$$$$$/ \______/ """ while 1: # Get the list sockets which are ready to be read through select read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[]) for sock in read_sockets: #New connection if sock == server_socket: # Handle the case in which there is a new connection recieved through server_socket sockfd, addr = server_socket.accept() CONNECTION_LIST.append(sockfd) username = sockfd.recv(1024) print "Client (%s, %s) connected" % addr # add a key - value pair to be able to map a connection to a username USERNAMES[sockfd.getpeername()] = username broadcast(server_socket, sockfd, "%s entered the room\n" % username) #Some incoming message from a client else: # Data recieved from client, process it try: #In Windows, sometimes when a TCP program closes abruptly, # a "Connection reset by peer" exception will be thrown data = sock.recv(RECV_BUFFER) if data: broadcast(server_socket, sock, "\r" + '[' + str(USERNAMES[sock.getpeername()]) + '] ' + data) #use the data structure previously defined to send the correct usernames else: # remove the socket that's broken if sock in SOCKET_LIST: SOCKET_LIST.remove(sock) except: broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr) print "Client (%s, %s) is offline" % addr sock.close() CONNECTION_LIST.remove(sock) continue server_socket.close()