У меня есть сервер заданий, который принимает запросы от клиента (есть 8 клиентов, отправляющих запросы с другого компьютера). Затем сервер отправляет «задание» («задание» - это просто исполняемый файл, который записывает файл результатов на диск), а в потоке «диспетчер заданий» ожидает выполнения задания. Когда задание выполняется, он отправляет клиенту сообщение о том, что файлы результатов готовы к копированию обратно клиенту.время чтения сокетов в recv
На главном потоке я использую select
читать входящие соединения от клиентов, а также рабочие места запросы:
readable, writable, exceptional = select.select(inputs, [], [])
, где inputs
список принятых соединений (розеток), и этот список также включает в себя server
разъем. Все сокеты установлены на неблокирующие. Для моего лучшего понимания, если этот вызов select
возвращает непустую readable
, это означает, что некоторые элементы inputs
имеют входящие данные, ожидающие чтения. Читаю данные, используя следующую логику (SIZE
константа):
for s in readable:
if s is not server:
try:
socket_ok = True
data = s.recv(SIZE)
except socket.error as e:
print ('ERROR socket error: ' + str(e))
socket_ok = False
except Exception as e:
print ('ERROR error reading from socket: ' + str(e))
socket_ok = False
if not socket_ok:
# do something
У меня есть 2 проблемы:
- Иногда я получаю
[Errno 110] Connection timed out
исключение, и я не понимаю, почему - если даже У меня есть читаемый сокет, разве это не значит, что у него есть данные для чтения? - Как бороться с этим исключением - часть
#do something
. Я могу выполнить «очистку» - удалить выполняемые задания, запрошенные таймером, и удалить мертвый сокет из списка. Но у меня нет возможности сообщить клиенту, что он должен прекратить ждать результатов этих заданий. В идеале я хотел бы как-то снова подключиться, потому что сами работы продолжают работать и дают результаты, которые я не хочу выбрасывать.
EDIT теперь я понял, что менеджер рабочих мест поток также имеет доступ к разъемам через Queue
например - если работа закончена, поток посылает «работы» сообщения через соответствующий сокет - так может быть методы send
и recv
одного и того же сокета вызывают какое-то состояние гонки? Но в любом случае я не вижу, как это может привести к ошибке «время ожидания соединения».
Попробуйте прочитать подробности здесь: https://pymotw.com/2/select/ –
@ReutSharabani, я прочитал его, и на самом деле мой код основан на нем. Но в моем коде вы можете видеть, что это исключение возникает при чтении из сокета в списке 'readbale', а ссылка, о которой вы указали, означает:« Все сокеты в читаемом списке имеют входящие данные, буферизированные и доступные для чтения »- поэтому это не объясняет проблему, которую я имею –