Форум сайта python.su
Всем привет!
Есть поток - функция, в которой сокет принимает сообщения. Для того, чтобы отслеживать таймаут, в этом потоке я запускаю еще один поток timeoutTimer , выполняющий функцию таймера, который вызывает self.tmr_callback по истечении таймаута. Так вот, во-первых, если я пытаюсь в коллбэке закрыть сокет, он закрывается, но клиент почему-то не реагирует на это, считает, что соединение открыто, а во-вторых, как сделать так, чтобы при срабатывании таймера корректно закрыть соединение и выйти из потока listen_to_client?
Помогите новичку, плиз!
listenThread = Thread( target=self.listen_to_client, args=(client, address, self.on_receive_callback, self.on_disconnected_callback) ) def tmrCallBack (client): client.close() print ('Timer callback called') def listen_to_client(self, client, address, on_receive_callback, on_disconnected_callback): # set a buffer size ( could be 2048 or 4096 / power of 2 ) size = 1024*1024 timeoutTimer = WatchdogTimer (5.0, self.tmr_callback, args=(client,), daemon = True) timeoutTimer.start() while True: try: d = client.recv(size) self.currentClient = client timeoutTimer.restart() if d: #messages = d.split(b'\n\r') messages = d.split(b'\0') for data in messages: if data: data = data.decode('utf-8') if self.debug: print(datetime.now(), self.serverName, 'CLIENT Data Received', address) if not self.debug_data: print('\n') if self.debug_data: print(data, '\n') if on_receive_callback: try: on_receive_callback(client, address, data) except Exception as e: if self.debug: print(datetime.now(), 'CLIENT Receive Callback Failed:', data, '\n', e, '\n') else: raise ValueError('CLIENT Disconnected') except Exception as e: if self.debug: print(datetime.now(), e, client, '\n') timeoutTimer.cancel() client.close() client_index = self.clients.index(client) self.clients.pop(client_index) if on_disconnected_callback: try: on_disconnected_callback(client, address) except Exception as e: print('on_close_callback failed\n', e, '\n') return False
Офлайн
IvanPletnevДа это просто ерунда какая-то. Вложения в коде должны быть не больше трёх уровней. Если у тебя больше уровней, то ты не знаешь, как код писать. А тема многопоточных программ сложная. Так что ты заведомо обрёк себя на проблемы.
Есть поток - функция, в которой сокет принимает сообщения.
Отредактировано py.user.next (Авг. 4, 2023 12:38:15)
Офлайн
py.user.nextХорошо. Я согласен, что не знаю, как правильно писать код. Поэтому и обратился на форум для новичков. Мне нужно контролировать таймаут по приёму сообщений, и если он наступает, закрывать соединение. Если подскажете, как это сделать, буду крайне благодарен.
Офлайн
IvanPletnevСделай скрипт новый, в котором одно соединение, в котором нет многопоточности. Элементарнейший скрипт с минимумом всего. И вот в нём попробуй поконтролировать таймаут. Когда у тебя не получится это сделать, тогда ты и поймёшь, что дело не в многопоточности.
Мне нужно контролировать таймаут по приёму сообщений, и если он наступает, закрывать соединение.
Отредактировано py.user.next (Авг. 4, 2023 14:05:33)
Офлайн
py.user.nextКажется, я понял, что нужно делать. Использовать свойство socket.timeout. И ловить исключение по его срабатыванию
И вот в нём попробуй поконтролировать таймаут.
Офлайн
import threading import time def worker(): for i in range(4): print(i) time.sleep(1) def main(): timeout = 3 thread = threading.Thread(target=worker) thread.daemon = True thread.start() thread.join(timeout) if thread.is_alive(): print('Поток остановлен принудительно') else: print("Поток отработал") if __name__ == "__main__": main()
Онлайн