socket — module socket

Ce module fournit l’accès à l’interface socket BSD.

Différence avec CPython

Pour des raisons d’efficacité et de cohérence, les objets socket de MicroPython implémentent directement une interface stream (de type fichier). Dans CPython, vous devez convertir un socket en objet de type fichier à l’aide de la méthode makefile(). Cette méthode est toujours prise en charge par MicroPython (mais elle est sans effet), donc lorsque la compatibilité avec CPython importe, veillez à l’utiliser.

Format(s) d’adresse de socket

Le format d’adresse de socket natif du module socket est un type de données opaque renvoyé par la fonction getaddrinfo(), qui doit être utilisée pour résoudre une adresse textuelle (y compris les adresses numériques)

sockaddr = socket.getaddrinfo('www.micropython.org', 80)[0][-1]
# You must use getaddrinfo() even for numeric addresses
sockaddr = socket.getaddrinfo('127.0.0.1', 80)[0][-1]
# Now you can use that address
sock.connect(sockaddr)

L’utilisation de getaddrinfo() est la manière la plus efficace (tant en termes de mémoire que de puissance de traitement) et la plus portable de travailler avec les adresses.

Le module socket fournit également une façon compatible avec CPython de spécifier des adresses à l’aide de tuples, comme décrit ci-dessous. Sur l’OpenMV Cam, le module socket est intégré ; les adresses numériques peuvent être données directement au format tuple, mais les noms de domaine doivent d’abord être résolus avec getaddrinfo().

En résumé :

  • Utilisez toujours getaddrinfo() pour résoudre les noms d’hôtes.

  • Les adresses sous forme de tuple décrites ci-dessous peuvent être utilisées comme raccourci pour les adresses numériques, pour des bidouilles rapides et un usage interactif.

Format d’adresse sous forme de tuple pour le module socket :

  • IPv4 : (ipv4_address, port), où ipv4_address est une chaîne contenant une adresse IPv4 numérique en notation pointée, par exemple "8.8.8.8", et port est un numéro de port entier dans la plage 1-65535. Les noms de domaine ne sont pas acceptés comme ipv4_address ; résolvez-les d’abord à l’aide de getaddrinfo().

  • IPv6 : (ipv6_address, port, flowinfo, scopeid), où ipv6_address est une chaîne contenant une adresse IPv6 numérique en notation à deux-points, par exemple "2001:db8::1", et port est un numéro de port entier dans la plage 1-65535. flowinfo doit être 0. scopeid est l’identifiant de portée d’interface pour les adresses lien-local. Les noms de domaine ne sont pas acceptés comme ipv6_address ; résolvez-les d’abord à l’aide de getaddrinfo().

Fonctions

socket.getaddrinfo(host: str, port: int, af: int = 0, type: int = 0, proto: int = 0, flags: int = 0, /) List[Tuple]

Traduit l’argument hôte/port en une séquence de 5-tuples contenant tous les arguments nécessaires à la création d’un socket connecté à ce service. Les arguments af, type et proto (qui ont la même signification que pour la fonction socket) peuvent être utilisés pour filtrer le type d’adresses renvoyées. Si un paramètre n’est pas spécifié ou est nul, toutes les combinaisons d’adresses peuvent être renvoyées (nécessitant un filtrage côté utilisateur).

La liste de 5-tuples résultante a la structure suivante

(family, type, proto, canonname, sockaddr)

L’exemple suivant montre comment se connecter à une url donnée

s = socket.socket()
# This assumes that if "type" is not specified, an address for
# SOCK_STREAM will be returned, which may be not true
s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])

Utilisation recommandée des paramètres de filtrage

s = socket.socket()
# Guaranteed to return an address which can be connect'ed to for
# stream operation.
s.connect(socket.getaddrinfo('www.micropython.org', 80, 0, SOCK_STREAM)[0][-1])

Différence avec CPython

CPython lève une exception socket.gaierror (sous-classe d”OSError) en cas d’erreur dans cette fonction. MicroPython n’a pas de socket.gaierror et lève directement OSError. Notez que les numéros d’erreur de getaddrinfo() forment un espace de noms distinct et peuvent ne pas correspondre aux numéros d’erreur du module errno. Pour distinguer les erreurs de getaddrinfo(), elles sont représentées par des nombres négatifs, tandis que les erreurs système standard sont des nombres positifs (les numéros d’erreur sont accessibles via la propriété e.args[0] d’un objet exception). L’usage de valeurs négatives est un détail provisoire qui pourra changer à l’avenir.

socket.inet_ntop(af: int, bin_addr: bytes) str

Convertit une adresse réseau binaire bin_addr de la famille d’adresses af donnée en une représentation textuelle

>>> socket.inet_ntop(socket.AF_INET, b"\x7f\0\0\1")
'127.0.0.1'
socket.inet_pton(af: int, txt_addr: str) bytes

Convertit une adresse réseau textuelle txt_addr de la famille d’adresses af donnée en une représentation binaire

>>> socket.inet_pton(socket.AF_INET, "1.2.3.4")
b'\x01\x02\x03\x04'

Constantes

socket.AF_INET: int

Famille d’adresses IPv4.

socket.AF_INET6: int

Famille d’adresses IPv6.

socket.SOCK_STREAM: int

Type de socket flux (TCP).

socket.SOCK_DGRAM: int

Type de socket datagramme (UDP).

socket.SOCK_RAW: int

Type de socket brut.

socket.IPPROTO_IP: int

Le niveau du protocole IP. Utilisé comme argument level de setsockopt() conjointement avec les options IP_*.

socket.IPPROTO_TCP: int

Le protocole TCP. Vous n’avez pas besoin de le passer à socket (le type de socket SOCK_STREAM le sélectionne automatiquement) ; son seul véritable usage est comme argument level de setsockopt() conjointement avec les options TCP_*.

socket.SOL_SOCKET: int

Le niveau d’option socket. Utilisé comme argument level de setsockopt() conjointement avec les options SO_*.

socket.SO_REUSEADDR: int

Autorise le socket à se lier à une adresse/un port qui est encore dans l’état TIME_WAIT.

socket.SO_BROADCAST: int

Permet l’envoi de datagrammes à une adresse de diffusion.

socket.SO_KEEPALIVE: int

Active la transmission périodique de sondes keep-alive sur un socket connecté.

socket.SO_SNDTIMEO: int

Délai d’expiration d’envoi, en millisecondes, passé comme argument value à setsockopt().

socket.SO_RCVTIMEO: int

Délai d’expiration de réception, en millisecondes, passé comme argument value à setsockopt().

socket.IP_ADD_MEMBERSHIP: int

Rejoint un groupe de multidiffusion. Une option de setsockopt() au niveau IPPROTO_IP.

socket.IP_DROP_MEMBERSHIP: int

Quitte un groupe de multidiffusion. Une option de setsockopt() au niveau IPPROTO_IP.

socket.TCP_NODELAY: int

Désactive l’algorithme de Nagle. Une option de setsockopt() au niveau IPPROTO_TCP.

socket.MSG_PEEK: int

Pour recv() / recvfrom() : renvoie les données sans les retirer de la file d’attente d’entrée.

socket.MSG_DONTWAIT: int

Pour recv() / recvfrom() : effectue l’opération en mode non bloquant.

Classes

class socket.socket(af: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP, /)

Crée un nouveau socket en utilisant la famille d’adresses, le type de socket et le numéro de protocole donnés. Spécifier proto n’est dans la plupart des cas pas requis (et non recommandé) ; l’argument type sélectionne automatiquement le protocole nécessaire

# Create STREAM TCP socket
socket(AF_INET, SOCK_STREAM)
# Create DGRAM UDP socket
socket(AF_INET, SOCK_DGRAM)
close() None

Marque le socket comme fermé et libère toutes les ressources. Une fois cela fait, toutes les opérations futures sur l’objet socket échoueront. L’extrémité distante recevra une indication EOF si le protocole le prend en charge.

Les sockets sont automatiquement fermés lorsqu’ils sont récupérés par le ramasse-miettes, mais il est recommandé de les fermer explicitement avec close() dès que vous avez fini de travailler avec eux.

bind(address: Any) None

Lie le socket à address. Le socket ne doit pas déjà être lié.

listen(backlog: int = 2) None

Permet à un serveur d’accepter des connexions. Si backlog est spécifié, il doit être au moins 0 (s’il est inférieur, il sera fixé à 0) ; il indique le nombre de connexions non acceptées que le système autorisera avant de refuser de nouvelles connexions. S’il n’est pas spécifié, une valeur raisonnable par défaut est choisie.

accept() Tuple['socket', Tuple]

Accepte une connexion. Le socket doit être lié à une adresse et être à l’écoute de connexions. La valeur de retour est une paire (conn, address) où conn est un nouvel objet socket utilisable pour envoyer et recevoir des données sur la connexion, et address est l’adresse liée au socket à l’autre extrémité de la connexion.

connect(address: Any) None

Se connecte à un socket distant à address.

send(bytes: bytes) int

Envoie des données au socket. Le socket doit être connecté à un socket distant. Renvoie le nombre d’octets envoyés, qui peut être inférieur à la longueur des données (« écriture courte »).

sendall(bytes: bytes) None

Envoie toutes les données au socket. Le socket doit être connecté à un socket distant. Contrairement à send(), cette méthode tentera d’envoyer toutes les données, en les envoyant morceau par morceau de manière consécutive.

Le comportement de cette méthode sur les sockets non bloquants est indéfini. Pour cette raison, sous MicroPython, il est recommandé d’utiliser plutôt la méthode write(), qui applique la même politique de « pas d’écritures courtes » pour les sockets bloquants, et renverra le nombre d’octets envoyés sur les sockets non bloquants.

recv(bufsize: int, flags: int = 0) bytes

Reçoit des données du socket. La valeur de retour est un objet bytes représentant les données reçues. La quantité maximale de données à recevoir en une fois est spécifiée par bufsize.

L’argument facultatif flags est un OU bit à bit d’indicateurs de message (MSG_PEEK, MSG_DONTWAIT), qui ont la même signification que dans CPython.

sendto(bytes: bytes, address: Any) int

Envoie des données au socket. Le socket ne doit pas être connecté à un socket distant, puisque le socket de destination est spécifié par address.

recvfrom(bufsize: int, flags: int = 0) Tuple[bytes, Tuple]

Reçoit des données du socket. La valeur de retour est une paire (bytes, address)bytes est un objet bytes représentant les données reçues et address est l’adresse du socket envoyant les données.

Voir la fonction recv() pour une explication de l’argument facultatif flags.

setsockopt(level: int, optname: int, value: int | bytes) None

Définit la valeur de l’option de socket donnée. Les constantes symboliques nécessaires sont définies dans le module socket (SO_*, etc.). La value peut être un entier ou un objet de type bytes représentant un tampon.

settimeout(value: float | None) None

Définit un délai d’expiration sur les opérations de socket bloquantes. L’argument value peut être un nombre à virgule flottante non négatif exprimant des secondes, ou None. Si une valeur non nulle est donnée, les opérations de socket ultérieures lèveront une exception OSError si la période de délai d’expiration s’est écoulée avant l’achèvement de l’opération. Si zéro est donné, le socket est mis en mode non bloquant. Si None est donné, le socket est mis en mode bloquant.

Une alternative portable et générique consiste à utiliser un objet select.poll. Cela permet d’attendre plusieurs objets en même temps (et pas seulement des sockets, mais des objets stream génériques qui prennent en charge le polling). Exemple

# Instead of:
s.settimeout(1.0)  # time in seconds
s.read(10)  # may timeout

# Use:
poller = select.poll()
poller.register(s, select.POLLIN)
res = poller.poll(1000)  # time in milliseconds
if not res:
    # s is still not ready for input, i.e. operation timed out

Différence avec CPython

CPython lève une exception socket.timeout en cas de délai d’expiration, qui est une sous-classe d”OSError. MicroPython lève à la place directement une OSError. Si vous utilisez except OSError: pour intercepter l’exception, votre code fonctionnera à la fois sous MicroPython et CPython.

setblocking(flag: bool) None

Définit le mode bloquant ou non bloquant du socket : si flag est faux, le socket est mis en mode non bloquant, sinon en mode bloquant.

Cette méthode est un raccourci pour certains appels à settimeout() :

  • sock.setblocking(True) est équivalent à sock.settimeout(None)

  • sock.setblocking(False) est équivalent à sock.settimeout(0)

makefile(mode: str = 'rb', buffering: int = 0, /) Any

Renvoie un objet fichier associé au socket. Le type exact renvoyé dépend des arguments fournis à makefile(). La prise en charge est limitée aux seuls modes binaires (« rb », « wb » et « rwb »). Les arguments de CPython : encoding, errors et newline ne sont pas pris en charge.

Différence avec CPython

Comme MicroPython ne prend pas en charge les flux tamponnés, la valeur du paramètre buffering est ignorée et traitée comme si elle valait 0 (sans tampon).

Différence avec CPython

La fermeture de l’objet fichier renvoyé par makefile() FERMERA également le socket d’origine.

read(size: int | None = None) bytes

Lit jusqu’à size octets depuis le socket. Renvoie un objet bytes. Si size n’est pas donné, lit toutes les données disponibles depuis le socket jusqu’à EOF ; de ce fait, la méthode ne reviendra pas tant que le socket n’est pas fermé. Cette fonction tente de lire autant de données que demandé (pas de « lectures courtes »). Cela peut toutefois ne pas être possible avec un socket non bloquant, et moins de données seront alors renvoyées.

readinto(buf: bytearray | memoryview, nbytes: int | None = None) int

Lit des octets dans buf. Si nbytes est spécifié, lit au plus ce nombre d’octets. Sinon, lit au plus len(buf) octets. Tout comme read(), cette méthode suit la politique de « pas de lectures courtes ».

Valeur de retour : nombre d’octets lus et stockés dans buf.

readline() bytes

Lit une ligne, se terminant par un caractère de saut de ligne.

Valeur de retour : la ligne lue.

write(buf: bytes) int

Écrit le tampon d’octets dans le socket. Cette fonction tentera d’écrire toutes les données dans un socket (pas d”« écritures courtes »). Cela peut toutefois ne pas être possible avec un socket non bloquant, et la valeur renvoyée sera inférieure à la longueur de buf.

Valeur de retour : nombre d’octets écrits.

Note

MicroPython n’implémente pas socket.error. CPython possède une exception obsolète socket.error qui est un alias d”OSError ; sous MicroPython, utilisez directement OSError pour intercepter les erreurs liées aux sockets.