← index #1375Issue #5806
Related · high · value 0.228
QUERY · ISSUE

unix usocket: External representation of (binary) addresses

openby pfalconopened 2015-07-11updated 2016-07-22
rfc

Ok, https://github.com/micropython/micropython/pull/1002 was closed, because approach of requiring usage of getaddrinfo() to pass addresses to socket functions certainly works. But there's opposite problem - how to show to user an address received from a socket function, e.g. accept(), which doesn't have any solution now. I can imagine following choices:

  1. Give up and return Python-standard tuple representation of addresses, then almost certainly also need to accept them to all other functions. Bunch more extra code, memory required for minimal socket server grows.
  2. Stay stubborn and make sockaddr a separate object, which will do conversion only on str() or repr(). No extra RAM overhead with this solution, but object will be more or less involved, e.g. standard Python tuple should be emulated.
  3. Stay stubborn and low-profile - just provide a function to convert binary address to Python tuple.

Thoughts?

CANDIDATE · ISSUE

unix extmod/uasyncio: socket.getaddrinfo and uasyncio.open_connection are incompatible

closedby tveopened 2020-03-26updated 2020-03-30
port-unix

In some situations it may be useful to decouple performing a dns lookup from opening a connection. An example is in Peter Hinch's mqtt_as library where the DNS lookup is performed once and not for every MQTT reconnect. The following test case (extracted from mqtt_as) works fine on esp32 (I believe also pybd and esp8266) but fails on unix:

# test that the output of socket.getaddrinfo can be fed into asyncio.open_connection

import sys
if sys.implementation.name == 'micropython' and sys.platform == 'linux':
    sys.path.append("/home/src/esp32/micropython/extmod")
try:
    import usocket as socket, uasyncio as asyncio
except:
    import socket, asyncio

async def test(peer_name):
    # perform DNS lookup
    addr = socket.getaddrinfo(peer_name, 80)[0][-1]
    print("Addr:", addr)
    # open connection
    s = await asyncio.open_connection(addr[0], addr[1])
    print("Connected!")

if __name__ == "__main__":
    asyncio.run(test('micropython.org'))

Sample output:

> python test-dns.py
Addr: ('176.58.119.26', 80)
Connected!
> ./pyboard test-dns.py
Addr: ('176.58.119.26', 80)
Connected!
> ../../micropython/ports/unix/micropython test-dns.py
Addr: bytearray(b'\x02\x00\x00P\xb0:w\x1a\x00\x00\x00\x00\x00\x00\x00\x00')
Traceback (most recent call last):
  File "test-dns.py", line 20, in <module>
  File "/home/src/esp32/micropython/extmod/uasyncio/core.py", line 210, in run
  File "/home/src/esp32/micropython/extmod/uasyncio/core.py", line 190, in run_until_complete
  File "/home/src/esp32/micropython/extmod/uasyncio/core.py", line 179, in run_until_complete
  File "test-dns.py", line 16, in test
  File "/home/src/esp32/micropython/extmod/uasyncio/stream.py", line 61, in open_connection
TypeError: can't convert 'int' object to str implicitly

I realize this probably is the way it is, but I wonder whether there's an easy work-around. The motivation is to be able to run the same code on unix for test&dev purposes.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied