9.11. Socketobjecten

De Python-interface naar de transportlaag is de socket.socket-klasse. Een socket vertegenwoordigt één eindpunt van een netwerkconversatie – een adres, een poort en het protocol (UDP of TCP) waarover de conversatie loopt. De hoofdstukken over hardwarebesturing openden UART-instanties om over een draad te praten; dit onderdeel opent socket-instanties om over het netwerk te praten. De vorm is dezelfde; de onderliggende dienst is alleen een stuk capabeler.

9.11.1. Een socket aanmaken

Drie argumenten beschrijven een socket: welke adresfamilie hij spreekt, welk sockettype hij biedt, en welk protocol hij gebruikt. De standaardwaarden dekken de gevallen die de rest van dit onderdeel gebruikt:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   # IPv4 TCP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    # IPv4 UDP

De twee constanten waar de toepassing in vrijwel elk geval tussen kiest:

  • AF_INET – IPv4-adressen (een numeriek IP plus een poort). De meest gangbare keuze. AF_INET6 is het IPv6-equivalent.

  • SOCK_STREAM – een TCP-verbinding, de betrouwbare bytestream. SOCK_DGRAM is het UDP-equivalent.

Het derde argument (het protocol) wordt op nul gelaten, wat de juiste standaard kiest op basis van de eerste twee. De volledige constructor staat gedocumenteerd op socket — socket-module.

9.11.2. Adressen op een socket

Een socketadres is een tuple van (host, port)

("192.168.1.50", 80)
("0.0.0.0", 8000)

De host is het IP-adres als string. De poort is het 16-bits geheel getal dat behandeld wordt op Poorten.

Een handvol speciale hoststrings is het waard om te kennen:

  • "0.0.0.0" betekent “elke IPv4-interface op dit apparaat”. Een server die aan dit adres is gebonden, accepteert verbindingen op elk adres dat de camera bezit.

  • "127.0.0.1" is localhost – verkeer ernaartoe verlaat het apparaat nooit. Handig om te testen.

  • "255.255.255.255" is het lokale broadcastadres. Een UDP-datagram dat hiernaartoe wordt gestuurd, gaat naar elk apparaat op het lokale segment.

Domeinnamen zoals "example.com" zijn geen geldige hoststrings in een socketadres. Ze moeten eerst worden omgezet naar een IP; Namen en DNS behandelt de getaddrinfo()-aanroep die dat doet.

9.11.3. De twee rollen

De levenscyclus van een socket hangt af van aan welke kant van de conversatie hij staat. Een client-socket roept connect() aan (of, voor UDP, gewoon sendto()) om met een bekende server te praten. Een server-socket roept bind() aan om een poort te claimen, en vervolgens ofwel listen() en accept() (voor TCP) of recvfrom() (voor UDP) om binnenkomend verkeer te ontvangen.

Dezelfde socket-constructor wordt in beide gevallen gebruikt; alleen de methoden die daarna worden aangeroepen verschillen. De volgende drie pagina’s lopen de praktische patronen door:

9.11.4. Een socket sluiten

Elke socket houdt een klein stukje besturingssysteemstatus vast (een poortreservering, buffers, de TCP-status van de verbinding). Wanneer de toepassing ermee klaar is, geeft close() die status vrij. Een vergeten socket is een trage lek die zich opstapelt; in een loop die verbindingen opent, zal het missen van een close uiteindelijk de pool van beschikbare sockets van de camera uitputten.

Het schoonste patroon is de with-instructie:

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(addr)
    s.send(b"GET / HTTP/1.0\r\n\r\n")
    ...
# socket is closed automatically here, even on error

Sockets implementeren het context-managerprotocol dat in het Python-overzicht wordt behandeld, dus het with-blok garandeert dat close() wordt aangeroepen, ongeacht of het blok normaal werd afgesloten of door het opwerpen van een uitzondering.

9.11.5. De socket-referentie

Deze en de volgende pagina’s lopen de API door in verhalende vorm. Voor de volledige referentie op argumentniveau van elke methode, elke vlag en elke constante die de module blootstelt, zie socket — socket-module. De referentie is ook de plek om te zoeken naar de minder gangbare operaties (socketopties, lidmaatschap van multicastgroepen, IPv6-scope-ID’s) die dit onderdeel niet behandelt.