При установке тайм-аута для сокета, socket.connect_ex()
становится неблокирующей операцией. Вот почему вы получаете ошибки EAGAIN
и EALREADY
при повторном вызове connect_ex()
в цикле - EAGAIN
при первом вызове означает, что соединение не может быть установлено немедленно и выполняется в фоновом режиме, а затем EALREADY
при последующих вызовах означает, что существующее соединение все еще выполняется и еще не завершено.
Ваш цикл просто выполняется до тех пор, пока соединение окончательно не завершится успехом или неудачей, независимо от того, сколько времени это займет. Таймаут сокета, который вы устанавливаете, не играет в эту логику.
Чтобы сделать то, что вы просите, запустите собственный таймер параллельно контуру соединения, а затем закройте сокет, если таймер истекает до того, как socket.connect_ex()
вернет свой окончательный результат.
Либо вообще избавиться от петли.
Вызовите socket.connect_ex()
один раз, и, если он вернет EAGAIN
, введите select.select()
, чтобы дождаться завершения соединения. Имеет параметр timeout
. Сокет TCP перейдет в состояние записи, если ожидающая попытка подключения успешно подключится к серверу. Если select()
истекло или сообщает об ошибке, закройте вместо этого сокет.
Или попробуйте использовать socket.create_connection()
, который также имеет параметр timeout
.