-
Notifications
You must be signed in to change notification settings - Fork 0
/
epoll_server.py
executable file
·449 lines (415 loc) · 32.7 KB
/
epoll_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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
'''
Created on Nov 20, 2020
@author: denis
'''
import socket
import csv
from threading import Thread
import select
import time
import datetime
class ServerHandler(Thread):
def __init__(self, sim_handler, host = "192.168.1.2", port = 8080, channels_csv_filename = "params.csv"):
super().__init__(daemon = True)
self.sim_handler = sim_handler
self.host = host
self.port = port
self.channels_csv_filename = channels_csv_filename
self.modem_1_RX_ch_num = -1 # Старый номер приемного канала модема подключенного к первому входу звуковой карты
self.modem_1_TX_ch_num = -1 # Старый номер передающего канала модема подключенного к первому входу звуковой карты
self.modem_2_RX_ch_num = -1 # Старый номер приемного канала модема подключенного ко второму входу звуковой карты
self.modem_2_TX_ch_num = -1 # Старый номер передающего канала модема подключенного ко второму входу звуковой карты
self.new_modem_1_RX_ch_num = None # Новый номер приемного канала модема подключенного к первому входу звуковой карты
self.new_modem_1_TX_ch_num = None # Новый номер передающего канала модема подключенного к первому входу звуковой карты
self.new_modem_2_RX_ch_num = None # Новый номер приемного канала модема подключенного ко второму входу звуковой карты
self.new_modem_2_TX_ch_num = None # Новый номер передающего канала модема подключенного ко второму входу звуковой карты
self.ch1_noise_already_on = False
self.ch2_noise_already_on = False
self.server_is_running = None
self.stop_server_flag = None
self.data_to_read = None
self.data_to_send = None
self.t1 = None # Время включения канала
self.t2 = None # Время выключения канала
self.conn_map = dict() # Служит для связи создаваемых объектов соединений с файловыми дескрипторами (числами), адресами модемов и каналами на прием и передачу
def start_sim(self, channel_num, restart_channels):
f = open(self.channels_csv_filename, "r")
i = 0 # Номер строки в csv файле
for r in csv.reader(f):
i += 1
if i == channel_num + 1:
floats = map(float, r)
self.ampl1, self.ampl2, self.tau, self.dop_shift, self.dop_fd, self.snr = floats
if any(self.ampl_mult):
print(f"Параметры симуляции:\n a1 - {self.ampl1}, a2 - {self.ampl2}, tau - {self.tau}, dop_shift - {self.dop_shift}, dop_fd - {self.dop_fd}, snr - {self.snr}")
print("Процесс симуляции запущен...\n")
self.sim_handler.ch1_restart = restart_channels[0]
self.sim_handler.ch2_restart = restart_channels[1]
if self.sim_handler.ch1_flow_graph_is_running and restart_channels[0] == True:
self.sim_handler.ch1_stop_sim() # Останавливаем симуляцию для переконфигурирования симулятора
if self.sim_handler.ch2_flow_graph_is_running and restart_channels[1] == True:
self.sim_handler.ch2_stop_sim() # Останавливаем симуляцию для переконфигурирования симулятора
self.sim_handler.ampl1 = self.ampl1 # Амплитуда первого луча
self.sim_handler.ampl2 = self.ampl2 # Амплитуда второго луча
self.sim_handler.tau = self.tau * 0.001 # Задержка второго луча относительно первого
self.sim_handler.dop_shift = self.dop_shift # Доплеровский сдвиг частоты
self.sim_handler.dop_fd = self.dop_fd # Доплеровское уширение (рассеивание)
self.sim_handler.snr = self.snr # Отношение сигнал-шум
self.sim_handler.on_off_out1 = self.ampl_mult[0]
self.sim_handler.on_off_out2 = self.ampl_mult[1]
self.sim_handler.ch1_en_silence_noise = self.en_noise[0]
self.sim_handler.ch2_en_silence_noise = self.en_noise[1]
if restart_channels[0] == restart_channels[1] == True:
self.sim_handler.ch1_start_sim() # Запуск симуляции канала
self.sim_handler.ch2_start_sim()
elif restart_channels[0] == True:
self.sim_handler.ch1_start_sim()
elif restart_channels[1] == True:
self.sim_handler.ch2_start_sim()
def read_data_handler(self, fileno):
if self.t1:
self.t2 = datetime.datetime.now()
dt = self.t2 - self.t1
self.t1 = 0
self.t2 = 0
print(f"Время до перестройки {dt.seconds}.{dt.microseconds} c.\n")
f = open('address.cfg', 'r')
addr_1_cfg, addr_2_cfg = map(int, f.read().split())
modem_address = self.data_to_read[0]
if modem_address == addr_1_cfg:
self.new_modem_1_RX_ch_num = self.data_to_read[2]
self.new_modem_1_TX_ch_num = self.data_to_read[1]
elif modem_address == addr_2_cfg:
self.new_modem_2_RX_ch_num = self.data_to_read[2]
self.new_modem_2_TX_ch_num = self.data_to_read[1]
else:
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f"Адрес модема: {modem_address} не допустим, ожидание...\n")
return
if None in [self.new_modem_1_TX_ch_num, self.new_modem_1_RX_ch_num]:
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f'Не получены номера каналов первого модема, ожидание...\ntx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}\n')
# self.send(bytearray([0]))
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
return
# conn.send(self.data_to_read)
elif None in [self.new_modem_2_TX_ch_num, self.new_modem_2_RX_ch_num]:
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f'Не получены номера каналов второго модема, ожидание...\ntx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}\n')
# self.send(bytearray([0]))
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
return
else:
if self.new_modem_1_TX_ch_num == self.new_modem_2_RX_ch_num ==\
self.new_modem_2_TX_ch_num == self.new_modem_1_RX_ch_num ==\
self.modem_1_TX_ch_num == self.modem_2_RX_ch_num ==\
self.modem_2_TX_ch_num == self.modem_1_RX_ch_num:
# Повторное включение того же канала,
# оба слышат друг друга - симметричный канал.
self.modem_1_RX_ch_num = self.new_modem_1_RX_ch_num
self.modem_1_TX_ch_num = self.new_modem_1_TX_ch_num
self.modem_2_RX_ch_num = self.new_modem_2_RX_ch_num
self.modem_2_TX_ch_num = self.new_modem_2_TX_ch_num
channel_number = self.modem_1_TX_ch_num
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f"Выбранный канал: {channel_number} совпадает с действующим, дополнительных действий не требуется")
print("Оба слышат друг друга - симметричный канал")
print(f"Комбинация номеров каналов: tx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}, tx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}")
print("Процесс симуляции продолжается со старыми значениями параметров канала")
self.t1 = datetime.datetime.now()
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
elif self.new_modem_2_TX_ch_num == self.new_modem_1_RX_ch_num and\
self.new_modem_1_TX_ch_num == self.new_modem_2_RX_ch_num ==\
self.modem_1_TX_ch_num == self.modem_2_RX_ch_num:
# Повторное включение первого канала, новый второй канал.
self.modem_1_RX_ch_num = self.new_modem_1_RX_ch_num
self.modem_1_TX_ch_num = self.new_modem_1_TX_ch_num
self.modem_2_RX_ch_num = self.new_modem_2_RX_ch_num
self.modem_2_TX_ch_num = self.new_modem_2_TX_ch_num
channel_number = self.modem_2_TX_ch_num
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print("Оба слышат друг друга - симметричный канал")
print(f"Выбранный новый второй канал: {channel_number}, первый канал совпадает с действующим")
print(f"Комбинация номеров каналов: tx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}, tx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}")
print("Запускаем второй канал с новыми параметрами, первый канал продолжает выполнение с действующими")
self.ampl_mult = [1, 1]
self.en_noise = [0, 0]
restart_channels = (0,1)
self.start_sim(channel_number, restart_channels)
self.ch2_noise_already_on = False
self.t1 = datetime.datetime.now()
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
elif self.new_modem_1_TX_ch_num == self.new_modem_2_RX_ch_num and\
self.new_modem_2_TX_ch_num == self.new_modem_1_RX_ch_num ==\
self.modem_2_TX_ch_num == self.modem_1_RX_ch_num:
# Повторное включение второго канала, новый первый канал.
self.modem_1_RX_ch_num = self.new_modem_1_RX_ch_num
self.modem_1_TX_ch_num = self.new_modem_1_TX_ch_num
self.modem_2_RX_ch_num = self.new_modem_2_RX_ch_num
self.modem_2_TX_ch_num = self.new_modem_2_TX_ch_num
channel_number = self.modem_1_TX_ch_num
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f"Выбранный новый первый канал: {channel_number}, второй канал совпадает с действующим")
print("Оба слышат друг друга - симметричный канал")
print(f"Комбинация номеров каналов: tx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}, tx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}")
print("Запускаем первый канал с новыми параметрами, второй канал продолжает выполнение с действующими")
self.ampl_mult = [1, 1]
self.en_noise = [0, 0]
restart_channels = (1,0)
self.start_sim(channel_number, restart_channels)
self.ch1_noise_already_on = False
self.t1 = datetime.datetime.now()
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
elif self.new_modem_1_TX_ch_num == self.new_modem_2_RX_ch_num ==\
self.new_modem_2_TX_ch_num == self.new_modem_1_RX_ch_num:
# Включение нового частотного канала,
# оба слышат друг друга - симметричный канал.
self.modem_1_RX_ch_num = self.new_modem_1_RX_ch_num
self.modem_1_TX_ch_num = self.new_modem_1_TX_ch_num
self.modem_2_RX_ch_num = self.new_modem_2_RX_ch_num
self.modem_2_TX_ch_num = self.new_modem_2_TX_ch_num
channel_number = self.modem_1_TX_ch_num
self.ampl_mult = [1, 1]
self.en_noise = [0, 0]
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f"Новый выбранный канал: {channel_number}")
print("Оба слышат друг друга - симметричный канал")
print(f"Комбинация номеров каналов: tx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}, tx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}")
self.ampl_mult = [1, 1]
self.en_noise = [0, 0]
restart_channels = (1,1)
self.start_sim(channel_number, restart_channels)
self.ch1_noise_already_on = False
self.ch2_noise_already_on = False
self.t1 = datetime.datetime.now()
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
elif self.new_modem_1_TX_ch_num == self.new_modem_2_RX_ch_num ==\
self.modem_1_TX_ch_num == self.modem_2_RX_ch_num:
# Повторное включение того же канала,
# второй слышит первого, первый не слышит второй.
self.modem_1_RX_ch_num = self.new_modem_1_RX_ch_num
self.modem_1_TX_ch_num = self.new_modem_1_TX_ch_num
self.modem_2_RX_ch_num = self.new_modem_2_RX_ch_num
self.modem_2_TX_ch_num = self.new_modem_2_TX_ch_num
channel_number = self.modem_1_TX_ch_num
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f"Выбранный канал: {channel_number} совпадает с действующим, дополнительных действий не требуется")
print("Второй слышит первого, первый не слышит второй")
print(f"Комбинация номеров каналов: tx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}, tx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}")
print("Процесс симуляции продолжается со старыми значениями параметров канала")
if not self.ch2_noise_already_on:
self.ampl_mult = [1, 0]
self.en_noise = [0, 1]
restart_channels = (0,1)
self.start_sim(channel_number, restart_channels)
self.ch2_noise_already_on = True
self.t1 = datetime.datetime.now()
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
elif self.new_modem_1_TX_ch_num == self.new_modem_2_RX_ch_num:
# Включение нового частотного канала,
# втрой слышит первого, первый не слышит второй.
self.modem_1_RX_ch_num = self.new_modem_1_RX_ch_num
self.modem_1_TX_ch_num = self.new_modem_1_TX_ch_num
self.modem_2_RX_ch_num = self.new_modem_2_RX_ch_num
self.modem_2_TX_ch_num = self.new_modem_2_TX_ch_num
channel_number = self.modem_1_TX_ch_num
self.ampl_mult = [1, 0]
self.en_noise = [0, 1]
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f"Выбранный канал: {channel_number}")
print("Второй слышит первого, первый не слышит второй")
print(f"Комбинация номеров каналов: tx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}, tx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}")
if not self.ch2_noise_already_on:
restart_channels = (1,1) # Рестартим оба канала, т.к. в канале с несовпадающими номерами каналов должен генерироваться белый шум
self.ch2_noise_already_on = True
else:
restart_channels = (1,0) # Рестартим только первый канал, т.к. во втором канале уже генерируется белый шум
self.start_sim(channel_number, restart_channels)
self.ch1_noise_already_on = False
self.t1 = datetime.datetime.now()
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
elif self.new_modem_2_TX_ch_num == self.new_modem_1_RX_ch_num ==\
self.modem_2_TX_ch_num == self.modem_1_RX_ch_num:
# Повторное включение того же канала,
# первый слышит второго, второй не слышит первого
self.modem_1_RX_ch_num = self.new_modem_1_RX_ch_num
self.modem_1_TX_ch_num = self.new_modem_1_TX_ch_num
self.modem_2_RX_ch_num = self.new_modem_2_RX_ch_num
self.modem_2_TX_ch_num = self.new_modem_2_TX_ch_num
channel_number = self.modem_2_TX_ch_num
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f"Выбранный канал: {channel_number} совпадает с действующим, дополнительных действий не требуется")
print("Первый слышит второго, второй не слышит первого")
print(f"Комбинация номеров каналов: tx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}, tx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}")
print("Процесс симуляции продолжается со старыми значениями параметров канала")
if not self.ch1_noise_already_on:
self.ampl_mult = [0, 1]
self.en_noise = [1, 0]
restart_channels = (1,0)
self.start_sim(channel_number, restart_channels)
self.ch1_noise_already_on = True
self.t1 = datetime.datetime.now()
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
elif self.new_modem_2_TX_ch_num == self.new_modem_1_RX_ch_num:
# первый слышит второй, второй не слышит первого
self.modem_1_RX_ch_num = self.new_modem_1_RX_ch_num
self.modem_1_TX_ch_num = self.new_modem_1_TX_ch_num
self.modem_2_RX_ch_num = self.new_modem_2_RX_ch_num
self.modem_2_TX_ch_num = self.new_modem_2_TX_ch_num
channel_number = self.modem_2_TX_ch_num
self.ampl_mult = [0, 1]
self.en_noise = [1, 0]
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f"Выбранный канал: {channel_number}")
print("Первый слышит второго, второй не слышит первого")
print(f"Комбинация номеров каналов: tx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}, tx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}")
if not self.ch1_noise_already_on:
restart_channels = (1,1) # Рестартим оба канала, т.к. в канале с несовпадающими номерами каналов должен генерироваться белый шум
self.ch1_noise_already_on = True
else:
restart_channels = (0,1)
self.start_sim(channel_number, restart_channels)
self.ch2_noise_already_on = False
self.t1 = datetime.datetime.now()
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
else:
# никто никого не слышит
self.modem_1_RX_ch_num = self.new_modem_1_RX_ch_num
self.modem_1_TX_ch_num = self.new_modem_1_TX_ch_num
self.modem_2_RX_ch_num = self.new_modem_2_RX_ch_num
self.modem_2_TX_ch_num = self.new_modem_2_TX_ch_num
channel_number = 1
self.ampl_mult = [0, 0]
self.en_noise = [1, 1]
print(f"Получено сообщение от клиента с адресом: {self.conn_map[fileno][1][0]}")
print(f"Сообщение: адрес - {modem_address}, tx - {self.data_to_read[1]}, rx - {self.data_to_read[2]}")
print(f"Недопустимая комбинация номеров каналов: tx1 - {self.new_modem_1_TX_ch_num}, rx1 - {self.new_modem_1_RX_ch_num}, tx2 - {self.new_modem_2_TX_ch_num}, rx2 - {self.new_modem_2_RX_ch_num}")
print("Процесс симуляции остановлен!\n")
if self.ch1_noise_already_on == self.ch2_noise_already_on == False:
restart_channels = (1,1)
self.start_sim(channel_number, restart_channels)
elif self.ch1_noise_already_on == False:
restart_channels = (1,0)
self.start_sim(channel_number, restart_channels)
elif self.ch2_noise_already_on == False:
restart_channels = (0,1)
self.start_sim(channel_number, restart_channels)
self.ch1_noise_already_on = True
self.ch2_noise_already_on = True
self.t1 = datetime.datetime.now()
self.data_to_send = self.data_to_read
self.epoll.modify(fileno, select.EPOLLOUT | select.EPOLLONESHOT)
# conn.send(self.data_to_read)
# if self.sim_handler.flow_graph_is_running == True:
# self.sim_handler.stop_sim() # Останавливаем симуляцию для переконфигурирования симулятора
def run(self):
try:
while True:
if not self.server_is_running:
serversocket = socket.socket()
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
serversocket.bind((self.host, self.port))
print(f"Сервер создан с параметрами: адрес {self.host}, порт {self.port}\nОжидание подключения клиентов...\n")
except socket.error:
print("Недопустимый адрес сервера или номер порта\n")
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
stock_ip = s.getsockname()[0]
print(f"Сервер будет запущен с параметрами: адрес - {stock_ip}, порт - 8080\nОжидание подключения клиентов...\n")
serversocket.bind((stock_ip, 8080))
serversocket.listen()
serversocket.setblocking(False) # Переводим сервер в неблокирующий режим, чтобы избежать застреваний в accept
self.server_is_running = True
self.epoll = select.epoll() # Создаем объект epoll
# Регистрируем наш интерес к событию чтения нашего сервера (его файлового дескриптора)
# Оно будет срабатывать каждый раз когда сервер акцептит новое соединение
self.epoll.register(serversocket.fileno(), select.EPOLLIN)
if self.stop_server_flag == True: # Останавливаем адаптацию по частоте при выставлении флага (по нажатию на кнопку "остановить симуляцию")
print("Сервер остановлен\n")
self.sim_handler.ch1_stop_sim()
self.sim_handler.ch2_stop_sim()
self.modem_1_RX_ch_num = -1 # Сбрасываем значения номеров каналов после остановки сервера
self.modem_1_TX_ch_num = -1
self.modem_2_RX_ch_num = -1
self.modem_2_TX_ch_num = -1
self.epoll.unregister(serversocket.fileno())
self.epoll.close()
serversocket.close()
self.server_is_running = False
while self.stop_server_flag == True:
time.sleep(0.01) # Задержка, облегчающая работу процессору, не удалять!!!
# Спрашиваем объект epoll о том, произошли ли какие либо события
# Параметр 1 говорит о том, что мы будем ждать одну секунду
if not self.epoll.closed:
events = self.epoll.poll(1)
for fileno, event in events: # События возвращаются в виде кортежа с файловым дескриптором и кодом события
# Если событие чтения возникло в сокете сервера, тогда создаем новое соединение
if fileno == serversocket.fileno():
conn, addr = serversocket.accept()
conn.setblocking(False)
print(f"Подключен клиент с адресом: {addr[0]}")
self.conn_map[conn.fileno()] = [conn, addr]
self.epoll.register(conn.fileno(), select.EPOLLIN) # Регистрируем наш интерес к событию чтения соединения с клиентом
elif event & select.EPOLLIN:
self.data_to_read = self.conn_map[fileno][0].recv(1024)
# print('recv ', self.data_to_read)
if self.data_to_read:
self.read_data_handler(fileno)
else:
self.epoll.modify(fileno, 0)
self.conn_map[fileno][0].shutdown(socket.SHUT_RDWR)
elif event & select.EPOLLOUT:
# print('send ', self.data_to_send)
self.conn_map[fileno][0].send(self.data_to_send)
self.data_to_send = b""
self.epoll.modify(fileno, select.EPOLLIN)
elif event & select.EPOLLHUP: # Обрабатываем дисконнект клиента
print(f"Клиент с адресом {self.conn_map[fileno][1][0]} закрыл соединение, ожидание переподключения...\n")
self.modem_1_RX_ch_num = None
self.modem_1_TX_ch_num = None
self.modem_2_RX_ch_num = None
self.modem_2_TX_ch_num = None
self.epoll.unregister(fileno) # Разрегистрируем наш интерес в событиях соединения с клиентом
self.conn_map[fileno][0].close() # Закрываем соединение с клиентом
del self.conn_map[fileno] # Удаляем файловый дескриптор из словаря
# else:
# self.epoll.modify(fileno, 0)
time.sleep(0.01) # Задержка, облегчающая работу процессору, не удалять!!!
except SystemExit:
if self.server_is_running:
self.sim_handler.ch1_stop_sim()
self.sim_handler.ch2_stop_sim()
self.epoll.unregister(serversocket.fileno())
self.epoll.close()
serversocket.close()
self.server_is_running = False
finally:
if self.server_is_running:
self.sim_handler.ch1_stop_sim()
self.sim_handler.ch2_stop_sim()
self.epoll.unregister(serversocket.fileno())
self.epoll.close()
serversocket.close()
self.server_is_running = False