Моя цель — создать интерфейс для постоянного прослушивания сокета... до тех пор, пока кто-нибудь из руководителей цепочки принятия решений не решит, что этого достаточно.
Это моя реализация, она не работает. Смешение потоков, сокетов, времени жизни объекта, параметров по умолчанию и языка, на котором я не слишком хорошо говорю, сбивает с толку.
Я тестировал разные аспекты этого кода по отдельности, и все было так, как ожидалось, за исключением строки, содержащей комментарий BUG, где я пытаюсь принудительно заблокировать основной поток до тех пор, пока сервер не услышит крик ребенка или не истечет тайм-аут, но вместо этого Recv() просто не видит изменения в реальном времени .
#!/usr/bin/env python3
import socket
import threading
import time
MAX_MSG_BYTES=1024
TEST_PORT=42668
def recv( s: socket.socket, alive: bool=True ) -> bytes:
'''
Accepts packets on a socket until terminated.
'''
s.settimeout(1) # 1 second
while alive:
print("'alive' is still", alive)
try:
data = s.recv(MAX_MSG_BYTES)
assert data # Empty packets were a problem.
yield data
except TimeoutError:
pass # expected error, any other is propagated up
def test_nonblocking_recv() -> None:
# Create 3 sockets - sever administrative, server content and client content.
# Bind the latter and forget about the former.
server_s = socket.create_server(('', TEST_PORT))
server_s.listen()
client_s = socket.create_connection(('localhost', TEST_PORT))
content_s = next(iter(server_s.accept())) # Accept 1 connection.
# client_s.sendall('If this is commented out, the server hangs.'.encode('utf8'))
alive = True
def read_one_message():
data = recv(content_s, alive)
print(next(iter(data))) # BUG this causes outside alive to not be seen
content_th = threading.Thread(target=read_one_message)
content_th.start()
time.sleep(3)
alive = False
print("But main thread 'alive' is", alive)
content_th.join()
assert threading.active_count() == 1
if __name__ == '__main__':
test_nonblocking_recv()
Подробнее здесь: https://stackoverflow.com/questions/790 ... -in-python