-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
148 lines (134 loc) · 4.82 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import socket
import threading
import time
conexoes = []
mensagens = []
login_list = []
adminconn = ""
flag_close = False
flag = True
def start():
global flag
global conexoes
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SERVER = socket.gethostbyname(socket.gethostname())
PORT = 8080
ADDR = (SERVER, PORT)
print(f"[INICIANDO SOCKET: {SERVER}:{PORT}]")
#Le arquivos de logins e senhas
with open("login.txt","r") as login:
for line in login:
login_list.append(line.strip())
try:
#Começa a esperar por conexões
server.bind(ADDR)
server.listen()
except:
return print('\nNão foi possível iniciar o servidor!\n')
#Loop para iniciar threads para cada client novo
while(flag):
conn, addr = server.accept()
thread = threading.Thread(target = clientThread, args=(conn, addr))
thread.start()
server.close()
#Envia historico de mensagens para client e atualiza seu historico de leitura visando igualar
#o marcador last para o total de mensagens enviadas
def individualMsg(conexao):
print(f"[ENVIANDO] Enviando mensagens para {conexao['addr']}")
for i in range(conexao['last'], len(mensagens)):
mensagem_de_envio = "msg=" + mensagens[i]
conexao['conn'].send(mensagem_de_envio.encode('utf-8'))
conexao['last'] = i + 1
time.sleep(0.2)
#Enviar mensagem para todos os clients exceto o que enviou
def sendAllMsg(conn):
global conexoes
for conexao in conexoes:
if(conexao["conn"] != conn):
individualMsg(conexao)
def clientThread(conn, addr):
print(f"[NOVA CONEXAO] Um novo usuario se conectou pelo endereço {addr}")
global conexoes
global mensagens
global adminconn
global flag
msg_dc = "!quit"
flag_client = True
flag_login = False
usern = conn.recv(2048).decode('utf-8')
passw = conn.recv(2048).decode('utf-8')
count = 0
#Autenticar login
for i in login_list:
login_split = i.split(":")
if login_split[0]==usern and login_split[1]==passw:
flag_login = True
break
count += 1
#Certificar que o usuario ja nao esta logado
for i in conexoes:
if i["username"] == usern:
flag_login = False
break
#Caso a autenticação funcione, segue
if flag_login:
succesmsg = "success"
conn.send(succesmsg.encode())
#armazena informações dos clients
mapa_da_conexao = {
"conn": conn,
"addr": addr,
"username": usern,
"last": 0,
"logado": True
}
if(usern == "admin"):
adminconn = conn
print(f"[CONFIRMAÇÃO LOGIN] {usern} se conectou pelo endereço {addr}")
conexoes.append(mapa_da_conexao)
individualMsg(mapa_da_conexao)
#loop para tratar mensagens
while flag_client:
msg = conn.recv(2048).decode('utf-8')
if msg.startswith("msg="):
mensagem_separada = msg.split("=")
mensagem = usern + "=" + mensagem_separada[1]
#sessao para comando shutdown
if(conn == adminconn):
if(mensagem_separada[1] == "!shutdown"):
contador = 10
#countdown de 10s
for i in range(10):
msg_shutdown = "msg=" + usern + "=O servidor irá encerrar em " + str(contador) + "s"
contador -= 1
conn.send(msg_shutdown.encode('utf-8'))
time.sleep(1)
#desconecta todos
for conexao in conexoes:
conexao["conn"].send(msg_dc.encode('utf-8'))
flag_client = False
flag = False
break
#desconecta individualmente quem requisitar sair
if(mensagem_separada[1] == "!quit"):
removeClient(conn)
flag_client = False
mensagem = "ADMIN=O usuário " + usern + " saiu da conversa"
#simplesmente agrega mensagem ao log de mensagens e envia para todos depois
mensagens.append(mensagem)
sendAllMsg(conn)
else:
removeClient(conn)
if not msg:
break
else:
succesmsg = "failure"
conn.send(succesmsg.encode())
#remover client individualmente
def removeClient(conn):
global conexoes
for conexao in conexoes:
if(conexao["conn"] == conn):
conn.close()
conexoes.remove(conexao)
start()