IsakViste icon

Chatroom.py

IsakViste | PRO | 04/10/19 01:23:22 PM UTC | 0 ⭐ | 280 👁️ | Never ⏰ | []
Python |

8.28 KB

|

None

|

0 👍

/

0 👎

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()

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎