ESP32 In MicroPython: Client Sockets |
Written by Harry Fairhead & Mike James | ||||||||||
Tuesday, 12 September 2023 | ||||||||||
Page 1 of 3 Sockets are the basis of communication over the internet. This extract is from Programming the ESP32 in MicroPython, part of the I Programmer Library and it shows you how to get started with sockets to implement HTTP and HTTPS clients. Programming the ESP32in MicroPython
|
type |
proto |
---|---|
SOCK_STREAM |
IPPROTO_TCP |
SOCK_DGRAM |
IPPROTO_UDP |
In a more general setting there could be more types of proto supported for each type.
Socket Addresses
After defining the type of connection, you need to specify the addresses involved in the connection. As sockets can be used to connect to a wide range of different types of network, the address format can vary a lot and not just be a simple URL or an IP address. For this reason sockets are used with their own internal address representation and you have to use the getaddrinfo method:
socket.getaddrinfo(host, port, af=0, type=0,
proto=0, flags=0)
The first two parameters are familiar and simple. The host has to be specified using a URL or an IP address. The second is the numeric port to use with the socket. The next three parameters are the same as used in creating the socket. In general you use the same parameter values for an address intended to be used with a socket as used to create the socket. If you don’t specify a parameter than getaddrinfo will return a list of tuples for each possible address type. Each tuple has the following format:
(af, type, proto, canonname, sockaddr)
where af, type and proto are as before and canonname is the canonical name for the address type and sockaddr is the actual address, which may also be a tuple. In the case of an IP address, the sockaddr is a tuple with the format:
(IP, port)
At the time of writing ESP32 only supports IPv4 and it only returns a list with a single tuple. The only really useful part of this tuple is the final element which is an IP tuple used by most of the socket methods. You could short circuit everything by simply creating the IP tuple and not use getaddrinfo. However, you should use getaddrinfo to allow for compatibility with the full sockets module and for future development.
For example:
ai = socket.getaddrinfo("www.example.com", 80,socket.AF_INET,socket.SOCK_DGRAM)
returns the list:
[(2, 1, 0, '', ('93.184.216.34', 80))]
and is it the final tuple:
('93.184.216.34', 80)
which we actually use in calls to socket methods. To extract this final tuple we use:
addr = ai[0][-1]
While on the subject of addresses, there are two functions which can be used to convert an IP address in “dotted” form to a byte value and vice versa:
socket.inet_ntop(socket.AF_INET,bytes)
gives the dotted text form and:
socket.inet_pton(socket.AF_INET,string)
gives the binary form of the IP address.