Page 1 of 2

socket settimeout problem.

Posted: Wed Jul 27, 2022 6:54 am
by nedoskiv
Hello,
I'm writing a simple wget script, but when try to connect to non existing IP or device that is offline, sock.connect take too long to rease an error

Code: Select all

>>> import usocket as socket
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.settimeout(2)
>>> sock.connect(("192.168.4.2",80))		// take more than 15 seconds
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 113] ECONNABORTED
Wondering am I doing something wrong or it just not work properly.
(tested on micropython version 1.19.1 and 1.18 - same result)

Re: socket settimeout problem.

Posted: Wed Jul 27, 2022 7:19 am
by davef
Something to try:

Code: Select all

import usocket

sock = usocket.socket(usocket.AF_INET, usocket.SOCK_DGRAM)
send_data = b'I am going to listen for 5 seconds'
sock.settimeout(5) #  this sets the listening time
Works for me. Maybe try usocket then DGRAM might narrow the problem down.

Re: socket settimeout problem.

Posted: Wed Jul 27, 2022 7:40 am
by nedoskiv
davef wrote:
Wed Jul 27, 2022 7:19 am
Something to try:

Code: Select all

import usocket

sock = usocket.socket(usocket.AF_INET, usocket.SOCK_DGRAM)
send_data = b'I am going to listen for 5 seconds'
sock.settimeout(5) #  this sets the listening time
Works for me. Maybe try usocket then DGRAM might narrow the problem down.
I'm actually using usocket (just updated original post)

and I do not want to listten on socket, I want to connect

Re: socket settimeout problem.

Posted: Wed Jul 27, 2022 8:10 am
by davef
I have never connected to a socket.

The next line in my script is:

Code: Select all

sent = sock.sendto(send_data, server_address)
I guess if server_address ('192.168.8.8', 10000) wasn't really there I might find the settimeout didn't apply there as well.

Hope someone else has the correct answer for you.

Re: socket settimeout problem.

Posted: Wed Jul 27, 2022 8:57 am
by davef
Had to have a bit of a search:
https://stackoverflow.com/questions/343 ... on-timeout
maybe setdefaulttimeout(2.0)

Re: socket settimeout problem.

Posted: Wed Jul 27, 2022 11:34 am
by nedoskiv
davef wrote:
Wed Jul 27, 2022 8:57 am
Had to have a bit of a search:
https://stackoverflow.com/questions/343 ... on-timeout
maybe setdefaulttimeout(2.0)

Code: Select all

>>> help (socket)
object <module 'usocket'> is of type module
  __name__ -- usocket
  __init__ -- <function>
  socket -- <class 'socket'>
  getaddrinfo -- <function>
  AF_INET -- 2
  AF_INET6 -- 10
  SOCK_STREAM -- 1
  SOCK_DGRAM -- 2
  SOCK_RAW -- 3
  IPPROTO_TCP -- 6
  IPPROTO_UDP -- 17
  IPPROTO_IP -- 0
  SOL_SOCKET -- 4095
  SO_REUSEADDR -- 4
  IP_ADD_MEMBERSHIP -- 3
there is no function about that in micropython
reading docs/discussions about sockets in python instead of micropython do not help

Anyway I found that this is known issue (on github) and is not yet fixed

https://github.com/micropython/micropython/issues/8326

Re: socket settimeout problem.

Posted: Wed Jul 27, 2022 1:56 pm
by marcidy
Try this example as-is:
https://github.com/micropython/micropyt ... _client.py

There's so much that can go wrong with local networking, are you 100% sure you are routing correctly, and everything happening on the address is correct?

Re: socket settimeout problem.

Posted: Wed Jul 27, 2022 2:24 pm
by karfas
marcidy wrote:
Wed Jul 27, 2022 1:56 pm
There's so much that can go wrong with local networking, are you 100% sure you are routing correctly, and everything happening on the address is correct?
@marcidy: The problem here is the duration of connect() when trying to reach an non-existing host.

Re: socket settimeout problem.

Posted: Wed Jul 27, 2022 4:09 pm
by marcidy
karfas wrote:
Wed Jul 27, 2022 2:24 pm
marcidy wrote:
Wed Jul 27, 2022 1:56 pm
There's so much that can go wrong with local networking, are you 100% sure you are routing correctly, and everything happening on the address is correct?
@marcidy: The problem here is the duration of connect() when trying to reach an non-existing host.
ha, missed that, thanks for clarifying

Re: socket settimeout problem.

Posted: Fri Jul 29, 2022 11:15 pm
by marcidy
I intended to look more into this, but so far haven't been able to pick up the debugger and get at it.

I don't see anything raised on github for this, which i think is appropriate in this case. The issue is definitely at the C code level *somewhere*.

The connect method is fairly transparent:

Code: Select all

STATIC mp_obj_t socket_connect(const mp_obj_t arg0, const mp_obj_t arg1) {
    socket_obj_t *self = MP_OBJ_TO_PTR(arg0);
    struct addrinfo *res;
    _socket_getaddrinfo(arg1, &res);
    MP_THREAD_GIL_EXIT();
    self->state = SOCKET_STATE_CONNECTED;
    int r = lwip_connect(self->fd, res->ai_addr, res->ai_addrlen);
    MP_THREAD_GIL_ENTER();
    lwip_freeaddrinfo(res);
    if (r != 0) {
        mp_raise_OSError(errno);
    }

    return mp_const_none;
}

The only two functions that are doing anything interesting are:

Code: Select all

    // ...
    _socket_getaddrinfo(arg1, &res);
    // ...
    int r = lwip_connect(self->fd, res->ai_addr, res->ai_addrlen);
    // ...
the getaddrinfo family of functions in that file result in blocking calls into the lwip library, and would be my first SWAG at where the problem is.

I don't yet know why "socket.connect" requires calling getaddrinfo, given that socket.conect is called with the results of calling socket.getaddrinfo(...) in python. I also haven't traced into lwip_connect enough to know if there's an issue there. Previously, i have traced the getaddrinfo calls down to the reasons they block, so im familiar with that code path.

So, really, a bunch of not-too-helpful information which says "raise it on github". I'd like to spend more time on it but i won't be able to do that until deep into next week at the earliest.