-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.py
164 lines (120 loc) · 4.49 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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import PySimpleGUI as sg
import socket
import threading
import warnings
warnings.filterwarnings("ignore")
sg.theme("DarkTeal5")
sg.set_options(font=("Helvetica", 13))
layout = [[sg.Button("Connect", key="-CONNECT-", size=(30, 1)),
sg.Button("Stop", key="-STOP-", disabled=True, size=(30, 1))],
[sg.Text("Host: X.X.X.X", key="-HOST-", size=(30, 1)),
sg.Text("Port: X.X.X.X", key="-PORT-", size=(30, 1))],
[sg.Text("Client List")], [sg.Multiline(size=(60, 15),
key="-CLIENTS-",
disabled=True)]]
window = sg.Window("Server", layout, size=(400, 275))
server = None
HOST_ADDR = "127.0.0.1"
HOST_PORT = 8080
client_name = " "
clients = []
clients_names = []
def start_server():
global server, HOST_ADDR, HOST_PORT, window
window["-CONNECT-"].update(disabled=True)
window["-STOP-"].update(disabled=False)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((HOST_ADDR, HOST_PORT))
server.listen(5)
thread = threading.Thread(target=accept_clients, args=(server, ))
thread.start()
window["-HOST-"].update("Host: " + HOST_ADDR)
window["-PORT-"].update("Port: " + str(HOST_PORT))
def stop_server():
global server, clients, clients_names, window
window["-CONNECT-"].update(disabled=False)
window["-STOP-"].update(disabled=True)
for c in clients:
c.close()
clients.clear()
clients_names.clear()
if server:
server.close()
server = None
exit()
def accept_clients(the_server):
global clients, window
try:
while True:
client, addr = the_server.accept()
clients.append(client)
thread = threading.Thread(target=send_receive_client_message,
args=(client, ))
thread.start()
except ConnectionAbortedError:
exit()
def send_receive_client_message(client_connection):
global server, client_name, clients, clients_names, window
client_name = client_connection.recv(4096).decode()
welcome_msg = "Welcome " + client_name + "! Press stop to quit." + ('\n' if len(clients_names) == 0 else '')
client_connection.send(welcome_msg.encode())
if len(clients_names) != 0:
if len(clients_names) == 1:
allclients_msg = '\n'+clients_names[0] + ' is in this chat.\n'
elif len(clients_names) == 2:
allclients_msg = '\n'+' & '.join(clients_names)
allclients_msg = allclients_msg + ' are in this chat.\n'
else:
allclients_msg = '\n' + ', '.join(
clients_names[:len(clients_names) - 1])
allclients_msg = allclients_msg + ' & ' + \
clients_names[len(clients_names) - 1] + \
' are in this chat.\n'
client_connection.send(allclients_msg.encode())
clients_names.append(client_name)
update_client_names_display(clients_names)
for client in clients:
if client != client_connection:
server_msg = client_name + ' has joined the chat!'
client.send(server_msg.encode())
try:
while True:
data = client_connection.recv(4096).decode()
if not data:
break
client_msg = data
idx = get_client_index(clients, client_connection)
sending_client_name = clients_names[idx]
for c in clients:
if c != client_connection:
server_msg = str(sending_client_name + "->" + client_msg)
c.send(server_msg.encode())
except OSError:
exit()
idx = get_client_index(clients, client_connection)
leaving_msg = clients_names[idx] + ' has left the chat!'
del clients_names[idx]
del clients[idx]
for client in clients:
server_msg = leaving_msg
client.send(server_msg.encode())
client_connection.close()
update_client_names_display(clients_names)
def get_client_index(client_list, curr_client):
idx = 0
for conn in client_list:
if conn == curr_client:
break
idx = idx + 1
return idx
def update_client_names_display(name_list):
window["-CLIENTS-"].update("\n".join(name_list))
while True:
event, values = window.read()
if event == sg.WINDOW_CLOSED:
break
if event == "-CONNECT-":
start_server()
elif event == "-STOP-":
stop_server()
window.close()