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
0 B
|👍
/👎