0

In Python, I need to wait until a device (which takes ~ 90 seconds to boot) is connected.

I tried a timeout of 120 seconds:

import socket
sock = socket.create_connection(("192.168.254.254", 1234), timeout=120)  
                                         # port 1234 for the direct API of the device

but after ~ 20 seconds it fails with:

Trackback (most recent call last):
File "C:\Python38\lib\urllib\request.py", line 1354, in do_open
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

Idem, I tried:

from urllib.request import urlopen
req = urlopen("http://192.168.254.254", timeout=120)  # the device also has a web interface

but after 21 seconds it fails with the same WinError 10060.

The device usually has finished boot after 90 seconds, so a timeout of 120 should be enough.

How to do this?

Is 20 seconds a maximum possible timeout on Windows?

Linked question (but not duplicate, it doesn't give the answer): here 20 seconds seems to be mentioned: TCP connection timeout is 20 or 21 seconds on *some* PCs when set to 500ms

This means that you wind up waiting for the underlying TCP operation to fail. This typically takes 20 seconds.

Is there a way to remove this TCP timeout limit of 20 seconds?

Basj
  • 41,386
  • 99
  • 383
  • 673
  • 4
    If it consistently takes about 90s to boot, would you bet better to sleep for 90-100s before trying to connect? Alternatively, you could try to connect in a `for _ in range(6):` loop and `break` when the connection is successful. – FiddleStix Jun 21 '23 at 10:52
  • @FiddleStix Yes I could try methods like this. But I wanted to know the core reason for timeout=120 being overriden by a (system?) timeout of 20 seconds. – Basj Jun 22 '23 at 06:36
  • 2
    This looks relevant to your question: https://medium.com/pipedrive-engineering/socket-timeout-an-important-but-not-simple-issue-with-python-4bb3c58386b4 – Zaq Jun 25 '23 at 04:05
  • Do these connection work after the other device has booted? Are both devices Windows OS or something else? – Life is complex Jun 29 '23 at 14:23
  • Which Windows are you using for this? – srn Jun 29 '23 at 19:09
  • What's the *Win* version? Check https://support.microsoft.com/en-us/topic/how-to-modify-the-tcp-ip-maximum-retransmission-time-out-7ae0982a-4963-fa7e-ee79-ff6d0da73db8. Set it to 6 or 7 and see if there is some difference (with reboots in between changes). – CristiFati Jun 30 '23 at 07:08
  • 2
    You will probably have to write a wrapper measuring the time spent in the `connect` and repeating it when it returns prematurely. Reason: *"the system network stack may also return a connection timeout error of its own regardless of any Python socket timeout setting."* (source: https://docs.python.org/3/library/socket.html#timeouts-and-the-connect-method) – VPfB Jun 30 '23 at 09:04
  • I tested on MacOS 13.3 and with python3. The code stopped waiting after 75s. So it looks like it comes from the underlying stack. – MarcC Jun 30 '23 at 12:02
  • Can you check this https://docs.oracle.com/cd/E23507_01/Search.20073/ATGSearchAdmin/html/s1207adjustingtcpsettingsforheavyload01.html#:~:text=On%20Windows%20platforms%2C%20the%20default,of%208.3%20queries%20per%20second. – KJG Jun 30 '23 at 14:27
  • Are you providing the address as a string? According to _socket.getaddrinfo() which is used by socket.create_connection() (via socket.getaddrinfo() ), host argument must be a string or None – srn Jul 01 '23 at 17:33
  • @srn Yes with a string (it was a typo, sorry). Thank you for your comment. – Basj Jul 03 '23 at 08:43

1 Answers1

-2

Try to do some fake CAPCHA that can't be failed with fake loadings until it loads and if it goes past 120 seconds you will fail the CAPCHA.

Winper
  • 14
  • 4