import socket import select import threading HOST = '' PORT = 7777 #### 1 #### # Version UDP def v_UDP(): with socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, 0) as s: s.bind((HOST, PORT)) while True: mess, addr = s.recvfrom(1500) print("Message:", mess) if not mess: break s.sendto(mess, addr) # Version TCP -1- Threads def v_TCP1(): with socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST, PORT)) s.listen(1) while True: conn, addr = s.accept() threading.Thread(None, f1, None, (conn,)).start() def f1(socket): while True: data = socket.recv(1024) if not data: break socket.send(data) socket.close() # Version TCP -2- Select def v_TCP2(): l = [] with socket.socket(socket.AF_INET6, socket.SOCK_STREAM, 0) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST, PORT)) s.listen(1) while True: l1, l2, l3 = select.select(l+[s], [], []) for i in l1: if i == s: conn, addr = i.accept() l.append(conn) else: message = f2(l, i) if not message: l.remove(i) i.close() def f2(l, socket): data = socket.recv(1024) if not data: return False for i in l: if i != socket: i.send(data) #print("Message:", data) return True #### 2 #### # Serveur de Chat # Code couleurs pour envoyer des message/infos colorees # https://stackoverflow.com/questions/287871/ class bcolors: HEADER = b'\033[95m' OKBLUE = b'\033[94m' OKGREEN = b'\033[92m' FAIL = b'\033[91m' RESET = b'\033[0m' BOLD = b'\033[1m' l = {"Public": []} nicks = {} # Fonction principal de Chatroom def chatroom(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST, PORT)) s.listen(1) while True: l1, l2, l3 = select.select(l["Public"]+[s], [], []) for i in l1: if i == s: # client joining conn, addr = i.accept() l["Public"].append(conn) nicks[conn] = str(addr[0]) client_connection(conn, addr, True) else: cont = f(i) # client leaving if not cont: l["Public"].remove(i) client_connection(conn, addr, False) i.close() # Reccupere les donnees, et verifie si l'utilisateurs veut utiliser des commandes # Renvoye False si le client se deconnecte # Renvoye True sinon def f(socket): data = socket.recv(1024) # If command is kill return False and kills the client connection to the server # If not continue cmd = command(data, socket) if not cmd: return False return True # Chat commands that the client has access too def command(cmd, socket): cmds = cmd.decode("utf-8").split(" ") #print(cmds) # KILL command if cmds[0] == "KILL" or cmds[0] == "KILL\n" or cmd == b"": socket.send(bcolors.HEADER + b"You are now disconnected!" + bcolors.RESET + b"\n\n") return False # JOIN command elif cmds[0] == "JOIN" or cmds[0] == "JOIN\n": if (len(cmds) < 2): socket.send(bcolors.FAIL + b"Channel name not indicated!" + bcolors.RESET + b"\n\n") elif l.get(cmds[1][:-1]) == None: l[cmds[1][:-1]] = [socket] socket.send(bcolors.HEADER + b"Channel " + bcolors.OKBLUE + cmds[1][:-1].encode("utf-8") + bcolors.HEADER + b" has been created!" + bcolors.RESET + b"\n\n") elif socket in l[cmds[1][:-1]]: socket.send(bcolors.FAIL + b"Can't join a channel you already joined!" + bcolors.RESET + b"\n\n") else: l[cmds[1][:-1]].append(socket) socket.send(bcolors.HEADER + b"You have joined channel " + bcolors.OKBLUE + cmds[1][:-1].encode("utf-8") + bcolors.HEADER + b"!" + bcolors.RESET + b"\n\n") # PART command elif cmds[0] == "PART" or cmds[0] == "PART\n": if (len(cmds) < 2): socket.send(bcolors.FAIL + b"Channel name not indicated!" + bcolors.RESET + b"\n\n") elif l.get(cmds[1][:-1]) == None: socket.send(bcolors.FAIL + b"Channel does not exist!" + bcolors.RESET + b"\n\n") elif cmds[1][:-1] == "Public": socket.send(bcolors.FAIL + b"Can't leave Public channel!" + bcolors.RESET + b"\n\n") elif socket not in l[cmds[1][:-1]]: socket.send(bcolors.FAIL + b"Can't leave a channel you haven't joined!" + bcolors.RESET + b"\n\n") else: l[cmds[1][:-1]].remove(socket) socket.send(bcolors.HEADER + b"You have left channel " + bcolors.OKBLUE + cmds[1][:-1].encode("utf-8") + bcolors.HEADER + b"!" + bcolors.RESET + b"\n\n") # LIST command elif cmds[0] == "LIST" or cmds[0] == "LIST\n": socket.send(bcolors.HEADER + b"List of Users:" + bcolors.RESET + b"\n") for i in nicks.values(): socket.send(b" - " + bcolors.OKGREEN + i.encode("utf-8") + bcolors.RESET + b"\n") socket.send(b"\n") # NICK command elif cmds[0] == "NICK" or cmds[0] == "NICK\n": if(len(cmds) > 1): nicks[socket] = cmds[1][:-1] socket.send(bcolors.HEADER + b"You are now known as: " + bcolors.OKGREEN + nicks.get(socket).encode("utf-8") + bcolors.RESET + b"\n\n") else: socket.send(bcolors.FAIL + b"Nickname not indicated!" + bcolors.RESET + b"\n\n") # MSG command elif cmds[0] == "MSG" or cmds[0] == "MSG\n": if (len(cmds) < 3): socket.send(bcolors.FAIL + b"Message & Channel not indicated!" + bcolors.RESET + b"\n\n") elif l.get(cmds[1]) != None: if socket in l[cmds[1]]: msg = ' '.join(cmds[2:]) for i in l[cmds[1]]: if cmds[1] != "Public": i.send(bcolors.OKBLUE + b"[" + cmds[1].encode("utf-8") + b"] " + bcolors.RESET) if i == socket: i.send(bcolors.OKGREEN + bcolors.BOLD + b"YOU: " + bcolors.RESET + msg.encode("utf-8")) else: i.send(bcolors.OKGREEN + nicks.get(socket).encode("utf-8") + b": " + bcolors.RESET + msg.encode("utf-8")) else: socket.send(bcolors.FAIL + b"You are not connected to this channel!" + bcolors.RESET + b"\n\n") else: socket.send(bcolors.FAIL + b"Channel does not exist!" + bcolors.RESET + b"\n\n") return True # Sends a message depending on whether the client is connecting or disconnecting def client_connection(client, addr, joining): # if joining or leaving server if joining: server_message(bcolors.HEADER + b"JOIN ") else: server_message(bcolors.HEADER + b"PART ") server_message(bcolors.OKBLUE + nicks.get(client).encode("utf-8") + bcolors.RESET + b"\n") # Send message to all clients connected to the server def server_message(byte): for i in l["Public"]: i.send(byte) chatroom()