summaryrefslogtreecommitdiff
path: root/docs/library/socket.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/library/socket.rst')
-rw-r--r--docs/library/socket.rst353
1 files changed, 353 insertions, 0 deletions
diff --git a/docs/library/socket.rst b/docs/library/socket.rst
new file mode 100644
index 000000000..39b848e59
--- /dev/null
+++ b/docs/library/socket.rst
@@ -0,0 +1,353 @@
+*******************************
+:mod:`usocket` -- socket module
+*******************************
+
+.. module:: usocket
+ :synopsis: socket module
+
+|see_cpython_module| :mod:`python:socket`.
+
+This module provides access to the BSD socket interface.
+
+.. admonition:: Difference to CPython
+ :class: attention
+
+ For efficiency and consistency, socket objects in MicroPython implement a `stream`
+ (file-like) interface directly. In CPython, you need to convert a socket to
+ a file-like object using `makefile()` method. This method is still supported
+ by MicroPython (but is a no-op), so where compatibility with CPython matters,
+ be sure to use it.
+
+Socket address format(s)
+------------------------
+
+The native socket address format of the ``usocket`` module is an opaque data type
+returned by `getaddrinfo` function, which must be used to resolve textual address
+(including numeric addresses)::
+
+ sockaddr = usocket.getaddrinfo('www.micropython.org', 80)[0][-1]
+ # You must use getaddrinfo() even for numeric addresses
+ sockaddr = usocket.getaddrinfo('127.0.0.1', 80)[0][-1]
+ # Now you can use that address
+ sock.connect(addr)
+
+Using `getaddrinfo` is the most efficient (both in terms of memory and processing
+power) and portable way to work with addresses.
+
+However, ``socket`` module (note the difference with native MicroPython
+``usocket`` module described here) provides CPython-compatible way to specify
+addresses using tuples, as described below. Note that depending on a
+:term:`MicroPython port`, ``socket`` module can be builtin or need to be
+installed from `micropython-lib` (as in the case of :term:`MicroPython Unix port`),
+and some ports still accept only numeric addresses in the tuple format,
+and require to use `getaddrinfo` function to resolve domain names.
+
+Summing up:
+
+* Always use `getaddrinfo` when writing portable applications.
+* Tuple addresses described below can be used as a shortcut for
+ quick hacks and interactive use, if your port supports them.
+
+Tuple address format for ``socket`` module:
+
+* IPv4: *(ipv4_address, port)*, where *ipv4_address* is a string with
+ dot-notation numeric IPv4 address, e.g. ``"8.8.8.8"``, and *port* is and
+ integer port number in the range 1-65535. Note the domain names are not
+ accepted as *ipv4_address*, they should be resolved first using
+ `usocket.getaddrinfo()`.
+* IPv6: *(ipv6_address, port, flowinfo, scopeid)*, where *ipv6_address*
+ is a string with colon-notation numeric IPv6 address, e.g. ``"2001:db8::1"``,
+ and *port* is an integer port number in the range 1-65535. *flowinfo*
+ must be 0. *scopeid* is the interface scope identifier for link-local
+ addresses. Note the domain names are not accepted as *ipv6_address*,
+ they should be resolved first using `usocket.getaddrinfo()`. Availability
+ of IPv6 support depends on a :term:`MicroPython port`.
+
+Functions
+---------
+
+.. function:: socket(af=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, /)
+
+ Create a new socket using the given address family, socket type and
+ protocol number. Note that specifying *proto* in most cases is not
+ required (and not recommended, as some MicroPython ports may omit
+ ``IPPROTO_*`` constants). Instead, *type* argument will select needed
+ protocol automatically::
+
+ # Create STREAM TCP socket
+ socket(AF_INET, SOCK_STREAM)
+ # Create DGRAM UDP socket
+ socket(AF_INET, SOCK_DGRAM)
+
+.. function:: getaddrinfo(host, port, af=0, type=0, proto=0, flags=0, /)
+
+ Translate the host/port argument into a sequence of 5-tuples that contain all the
+ necessary arguments for creating a socket connected to that service. Arguments
+ *af*, *type*, and *proto* (which have the same meaning as for the `socket()` function)
+ can be used to filter which kind of addresses are returned. If a parameter is not
+ specified or zero, all combinations of addresses can be returned (requiring
+ filtering on the user side).
+
+ The resulting list of 5-tuples has the following structure::
+
+ (family, type, proto, canonname, sockaddr)
+
+ The following example shows how to connect to a given url::
+
+ s = usocket.socket()
+ # This assumes that if "type" is not specified, an address for
+ # SOCK_STREAM will be returned, which may be not true
+ s.connect(usocket.getaddrinfo('www.micropython.org', 80)[0][-1])
+
+ Recommended use of filtering params::
+
+ s = usocket.socket()
+ # Guaranteed to return an address which can be connect'ed to for
+ # stream operation.
+ s.connect(usocket.getaddrinfo('www.micropython.org', 80, 0, SOCK_STREAM)[0][-1])
+
+ .. admonition:: Difference to CPython
+ :class: attention
+
+ CPython raises a ``socket.gaierror`` exception (`OSError` subclass) in case
+ of error in this function. MicroPython doesn't have ``socket.gaierror``
+ and raises OSError directly. Note that error numbers of `getaddrinfo()`
+ form a separate namespace and may not match error numbers from
+ the :mod:`uerrno` module. To distinguish `getaddrinfo()` errors, they are
+ represented by negative numbers, whereas standard system errors are
+ positive numbers (error numbers are accessible using ``e.args[0]`` property
+ from an exception object). The use of negative values is a provisional
+ detail which may change in the future.
+
+.. function:: inet_ntop(af, bin_addr)
+
+ Convert a binary network address *bin_addr* of the given address family *af*
+ to a textual representation::
+
+ >>> usocket.inet_ntop(usocket.AF_INET, b"\x7f\0\0\1")
+ '127.0.0.1'
+
+.. function:: inet_pton(af, txt_addr)
+
+ Convert a textual network address *txt_addr* of the given address family *af*
+ to a binary representation::
+
+ >>> usocket.inet_pton(usocket.AF_INET, "1.2.3.4")
+ b'\x01\x02\x03\x04'
+
+Constants
+---------
+
+.. data:: AF_INET
+ AF_INET6
+
+ Address family types. Availability depends on a particular :term:`MicroPython port`.
+
+.. data:: SOCK_STREAM
+ SOCK_DGRAM
+
+ Socket types.
+
+.. data:: IPPROTO_UDP
+ IPPROTO_TCP
+
+ IP protocol numbers. Availability depends on a particular :term:`MicroPython port`.
+ Note that you don't need to specify these in a call to `usocket.socket()`,
+ because `SOCK_STREAM` socket type automatically selects `IPPROTO_TCP`, and
+ `SOCK_DGRAM` - `IPPROTO_UDP`. Thus, the only real use of these constants
+ is as an argument to `setsockopt()`.
+
+.. data:: usocket.SOL_*
+
+ Socket option levels (an argument to `setsockopt()`). The exact
+ inventory depends on a :term:`MicroPython port`.
+
+.. data:: usocket.SO_*
+
+ Socket options (an argument to `setsockopt()`). The exact
+ inventory depends on a :term:`MicroPython port`.
+
+Constants specific to WiPy:
+
+.. data:: IPPROTO_SEC
+
+ Special protocol value to create SSL-compatible socket.
+
+class socket
+============
+
+Methods
+-------
+
+.. method:: socket.close()
+
+ Mark the socket closed and release all resources. Once that happens, all future operations
+ on the socket object will fail. The remote end will receive EOF indication if
+ supported by protocol.
+
+ Sockets are automatically closed when they are garbage-collected, but it is recommended
+ to `close()` them explicitly as soon you finished working with them.
+
+.. method:: socket.bind(address)
+
+ Bind the socket to *address*. The socket must not already be bound.
+
+.. method:: socket.listen([backlog])
+
+ Enable a server to accept connections. If *backlog* is specified, it must be at least 0
+ (if it's lower, it will be set to 0); and specifies the number of unaccepted connections
+ that the system will allow before refusing new connections. If not specified, a default
+ reasonable value is chosen.
+
+.. method:: socket.accept()
+
+ Accept a connection. The socket must be bound to an address and listening for connections.
+ The return value is a pair (conn, address) where conn is a new socket object usable to send
+ and receive data on the connection, and address is the address bound to the socket on the
+ other end of the connection.
+
+.. method:: socket.connect(address)
+
+ Connect to a remote socket at *address*.
+
+.. method:: socket.send(bytes)
+
+ Send data to the socket. The socket must be connected to a remote socket.
+ Returns number of bytes sent, which may be smaller than the length of data
+ ("short write").
+
+.. method:: socket.sendall(bytes)
+
+ Send all data to the socket. The socket must be connected to a remote socket.
+ Unlike `send()`, this method will try to send all of data, by sending data
+ chunk by chunk consecutively.
+
+ The behaviour of this method on non-blocking sockets is undefined. Due to this,
+ on MicroPython, it's recommended to use `write()` method instead, which
+ has the same "no short writes" policy for blocking sockets, and will return
+ number of bytes sent on non-blocking sockets.
+
+.. method:: socket.recv(bufsize)
+
+ Receive data from the socket. The return value is a bytes object representing the data
+ received. The maximum amount of data to be received at once is specified by bufsize.
+
+.. method:: socket.sendto(bytes, address)
+
+ Send data to the socket. The socket should not be connected to a remote socket, since the
+ destination socket is specified by *address*.
+
+.. method:: socket.recvfrom(bufsize)
+
+ Receive data from the socket. The return value is a pair *(bytes, address)* where *bytes* is a
+ bytes object representing the data received and *address* is the address of the socket sending
+ the data.
+
+.. method:: socket.setsockopt(level, optname, value)
+
+ Set the value of the given socket option. The needed symbolic constants are defined in the
+ socket module (SO_* etc.). The *value* can be an integer or a bytes-like object representing
+ a buffer.
+
+.. method:: socket.settimeout(value)
+
+ **Note**: Not every port supports this method, see below.
+
+ Set a timeout on blocking socket operations. The value argument can be a nonnegative floating
+ point number expressing seconds, or None. If a non-zero value is given, subsequent socket operations
+ will raise an `OSError` exception if the timeout period value has elapsed before the operation has
+ completed. If zero is given, the socket is put in non-blocking mode. If None is given, the socket
+ is put in blocking mode.
+
+ Not every :term:`MicroPython port` supports this method. A more portable and
+ generic solution is to use `uselect.poll` object. This allows to wait on
+ multiple objects at the same time (and not just on sockets, but on generic
+ `stream` objects which support polling). Example::
+
+ # Instead of:
+ s.settimeout(1.0) # time in seconds
+ s.read(10) # may timeout
+
+ # Use:
+ poller = uselect.poll()
+ poller.register(s, uselect.POLLIN)
+ res = poller.poll(1000) # time in milliseconds
+ if not res:
+ # s is still not ready for input, i.e. operation timed out
+
+ .. admonition:: Difference to CPython
+ :class: attention
+
+ CPython raises a ``socket.timeout`` exception in case of timeout,
+ which is an `OSError` subclass. MicroPython raises an OSError directly
+ instead. If you use ``except OSError:`` to catch the exception,
+ your code will work both in MicroPython and CPython.
+
+.. method:: socket.setblocking(flag)
+
+ Set blocking or non-blocking mode of the socket: if flag is false, the socket is set to non-blocking,
+ else to blocking mode.
+
+ This method is a shorthand for certain `settimeout()` calls:
+
+ * ``sock.setblocking(True)`` is equivalent to ``sock.settimeout(None)``
+ * ``sock.setblocking(False)`` is equivalent to ``sock.settimeout(0)``
+
+.. method:: socket.makefile(mode='rb', buffering=0, /)
+
+ Return a file object associated with the socket. The exact returned type depends on the arguments
+ given to makefile(). The support is limited to binary modes only ('rb', 'wb', and 'rwb').
+ CPython's arguments: *encoding*, *errors* and *newline* are not supported.
+
+ .. admonition:: Difference to CPython
+ :class: attention
+
+ As MicroPython doesn't support buffered streams, values of *buffering*
+ parameter is ignored and treated as if it was 0 (unbuffered).
+
+ .. admonition:: Difference to CPython
+ :class: attention
+
+ Closing the file object returned by makefile() WILL close the
+ original socket as well.
+
+.. method:: socket.read([size])
+
+ Read up to size bytes from the socket. Return a bytes object. If *size* is not given, it
+ reads all data available from the socket until EOF; as such the method will not return until
+ the socket is closed. This function tries to read as much data as
+ requested (no "short reads"). This may be not possible with
+ non-blocking socket though, and then less data will be returned.
+
+.. method:: socket.readinto(buf[, nbytes])
+
+ Read bytes into the *buf*. If *nbytes* is specified then read at most
+ that many bytes. Otherwise, read at most *len(buf)* bytes. Just as
+ `read()`, this method follows "no short reads" policy.
+
+ Return value: number of bytes read and stored into *buf*.
+
+.. method:: socket.readline()
+
+ Read a line, ending in a newline character.
+
+ Return value: the line read.
+
+.. method:: socket.write(buf)
+
+ Write the buffer of bytes to the socket. This function will try to
+ write all data to a socket (no "short writes"). This may be not possible
+ with a non-blocking socket though, and returned value will be less than
+ the length of *buf*.
+
+ Return value: number of bytes written.
+
+.. exception:: usocket.error
+
+ MicroPython does NOT have this exception.
+
+ .. admonition:: Difference to CPython
+ :class: attention
+
+ CPython used to have a ``socket.error`` exception which is now deprecated,
+ and is an alias of `OSError`. In MicroPython, use `OSError` directly.