socket — socket-module¶
Deze module biedt toegang tot de BSD-socketinterface.
Verschil met CPython
Voor efficiëntie en consistentie implementeren socket-objecten in MicroPython rechtstreeks een stream (bestandsachtige) interface. In CPython moet je een socket converteren naar een bestandsachtig object met de methode makefile(). Deze methode wordt nog steeds ondersteund door MicroPython (maar doet niets), dus waar compatibiliteit met CPython van belang is, zorg dat je deze gebruikt.
Socketadresformaat(en)¶
Het native socketadresformaat van de socket-module is een opaak gegevenstype dat wordt geretourneerd door de functie getaddrinfo(), die gebruikt moet worden om tekstuele adressen (inclusief numerieke adressen) te resolveren:
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)
Het gebruik van getaddrinfo() is de meest efficiënte (zowel qua geheugen als verwerkingskracht) en draagbare manier om met adressen te werken.
De socket-module biedt ook een CPython-compatibele manier om adressen op te geven met tuples, zoals hieronder beschreven. Op de OpenMV Cam is de socket-module ingebouwd; numerieke adressen mogen rechtstreeks in het tuple-formaat worden opgegeven, maar domeinnamen moeten eerst worden geresolveerd met getaddrinfo().
Samengevat:
Gebruik altijd
getaddrinfo()om hostnamen te resolveren.De hieronder beschreven tuple-adressen kunnen worden gebruikt als snelkoppeling voor numerieke adressen, voor snelle hacks en interactief gebruik.
Tuple-adresformaat voor de socket-module:
IPv4: (ipv4_address, port), waarbij ipv4_address een string is met een numeriek IPv4-adres in puntnotatie, bijv.
"8.8.8.8", en port een geheel poortnummer is in het bereik 1-65535. Domeinnamen worden niet geaccepteerd als ipv4_address; resolveer ze eerst metgetaddrinfo().IPv6: (ipv6_address, port, flowinfo, scopeid), waarbij ipv6_address een string is met een numeriek IPv6-adres in dubbelepuntnotatie, bijv.
"2001:db8::1", en port een geheel poortnummer is in het bereik 1-65535. flowinfo moet 0 zijn. scopeid is de interface-scope-identifier voor link-local adressen. Domeinnamen worden niet geaccepteerd als ipv6_address; resolveer ze eerst metgetaddrinfo().
Functies¶
- socket.getaddrinfo(host: str, port: int, af: int = 0, type: int = 0, proto: int = 0, flags: int = 0, /) List[Tuple]¶
Vertaal het host/port-argument naar een reeks van 5-tuples die alle benodigde argumenten bevatten voor het maken van een socket die verbonden is met die service. De argumenten af, type en proto (die dezelfde betekenis hebben als voor de functie
socket) kunnen worden gebruikt om te filteren welk soort adressen worden geretourneerd. Als een parameter niet is opgegeven of nul is, kunnen alle combinaties van adressen worden geretourneerd (waarbij filtering aan de gebruikerszijde vereist is).De resulterende lijst van 5-tuples heeft de volgende structuur:
(family, type, proto, canonname, sockaddr)Het volgende voorbeeld laat zien hoe je verbinding maakt met een gegeven url:
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])
Aanbevolen gebruik van filterparameters:
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])
Verschil met CPython
CPython veroorzaakt een
socket.gaierror-uitzondering (subklasse vanOSError) in geval van een fout in deze functie. MicroPython heeft geensocket.gaierroren veroorzaakt rechtstreeks OSError. Merk op dat de foutnummers vangetaddrinfo()een aparte namespace vormen en mogelijk niet overeenkomen met foutnummers uit deerrno-module. Omgetaddrinfo()-fouten te onderscheiden, worden ze weergegeven door negatieve getallen, terwijl standaard systeemfouten positieve getallen zijn (foutnummers zijn toegankelijk via de eigenschape.args[0]van een uitzonderingsobject). Het gebruik van negatieve waarden is een voorlopig detail dat in de toekomst kan veranderen.
Constanten¶
- socket.IPPROTO_IP: int¶
Het IP-protocolniveau. Gebruikt als het level-argument voor
setsockopt()samen met deIP_*-opties.
- socket.IPPROTO_TCP: int¶
Het TCP-protocol. Je hoeft dit niet door te geven aan
socket(het sockettypeSOCK_STREAMselecteert het automatisch); het enige werkelijke gebruik ervan is als het level-argument voorsetsockopt()samen met deTCP_*-opties.
- socket.SOL_SOCKET: int¶
Het socketoptieniveau. Gebruikt als het level-argument voor
setsockopt()samen met deSO_*-opties.
- socket.SO_REUSEADDR: int¶
Sta de socket toe om te binden aan een adres/poort dat zich nog in de
TIME_WAIT-status bevindt.
- socket.SO_KEEPALIVE: int¶
Schakel periodieke verzending van keep-alive-probes in op een verbonden socket.
- socket.SO_SNDTIMEO: int¶
Verzendtime-out, in milliseconden, doorgegeven als het value-argument aan
setsockopt().
- socket.SO_RCVTIMEO: int¶
Ontvangsttime-out, in milliseconden, doorgegeven als het value-argument aan
setsockopt().
- socket.IP_ADD_MEMBERSHIP: int¶
Word lid van een multicastgroep. Een
setsockopt()-optie opIPPROTO_IP-niveau.
- socket.IP_DROP_MEMBERSHIP: int¶
Verlaat een multicastgroep. Een
setsockopt()-optie opIPPROTO_IP-niveau.
- socket.TCP_NODELAY: int¶
Schakel Nagle’s algoritme uit. Een
setsockopt()-optie opIPPROTO_TCP-niveau.
- socket.MSG_PEEK: int¶
Voor
recv()/recvfrom(): retourneer data zonder deze uit de invoerwachtrij te verwijderen.
- socket.MSG_DONTWAIT: int¶
Voor
recv()/recvfrom(): voer de bewerking uit in niet-blokkerende modus.
Klassen¶
- class socket.socket(af: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP, /)¶
Maak een nieuwe socket aan met de gegeven adresfamilie, sockettype en protocolnummer. Het opgeven van proto is in de meeste gevallen niet vereist (en niet aanbevolen); het type-argument selecteert automatisch het benodigde protocol:
# Create STREAM TCP socket socket(AF_INET, SOCK_STREAM) # Create DGRAM UDP socket socket(AF_INET, SOCK_DGRAM)
- close() None¶
Markeer de socket als gesloten en geef alle resources vrij. Zodra dat gebeurt, mislukken alle toekomstige bewerkingen op het socket-object. De andere kant ontvangt een EOF-indicatie indien dit door het protocol wordt ondersteund.
Sockets worden automatisch gesloten wanneer ze door de garbage collector worden opgeruimd, maar het is aanbevolen om ze expliciet te
close()zodra je klaar bent met werken.
- listen(backlog: int = 2) None¶
Stel een server in staat om verbindingen te accepteren. Als backlog is opgegeven, moet het minstens 0 zijn (is het lager, dan wordt het op 0 gezet); het geeft het aantal niet-geaccepteerde verbindingen aan dat het systeem toestaat voordat nieuwe verbindingen worden geweigerd. Indien niet opgegeven, wordt een redelijke standaardwaarde gekozen.
- accept() Tuple['socket', Tuple]¶
Accepteer een verbinding. De socket moet gebonden zijn aan een adres en luisteren naar verbindingen. De retourwaarde is een paar (conn, address) waarbij conn een nieuw socket-object is dat bruikbaar is om data te verzenden en ontvangen op de verbinding, en address het adres is dat gebonden is aan de socket aan de andere kant van de verbinding.
- send(bytes: bytes) int¶
Verzend data naar de socket. De socket moet verbonden zijn met een externe socket. Retourneert het aantal verzonden bytes, wat kleiner kan zijn dan de lengte van de data (“short write”).
- sendall(bytes: bytes) None¶
Verzend alle data naar de socket. De socket moet verbonden zijn met een externe socket. In tegenstelling tot
send()zal deze methode proberen alle data te verzenden, door de data stuk voor stuk achtereenvolgens te verzenden.Het gedrag van deze methode op niet-blokkerende sockets is ongedefinieerd. Daarom wordt op MicroPython aanbevolen om in plaats daarvan de methode
write()te gebruiken, die hetzelfde “geen short writes”-beleid heeft voor blokkerende sockets en het aantal verzonden bytes retourneert op niet-blokkerende sockets.
- recv(bufsize: int, flags: int = 0) bytes¶
Ontvang data van de socket. De retourwaarde is een bytes-object dat de ontvangen data vertegenwoordigt. De maximale hoeveelheid data die in één keer kan worden ontvangen, wordt opgegeven met bufsize.
Het optionele flags-argument is een bitsgewijze OR van berichtvlaggen (
MSG_PEEK,MSG_DONTWAIT), die dezelfde betekenis hebben als in CPython.
- sendto(bytes: bytes, address: Any) int¶
Verzend data naar de socket. De socket mag niet verbonden zijn met een externe socket, aangezien de bestemmingssocket wordt opgegeven door address.
- recvfrom(bufsize: int, flags: int = 0) Tuple[bytes, Tuple]¶
Ontvang data van de socket. De retourwaarde is een paar (bytes, address) waarbij bytes een bytes-object is dat de ontvangen data vertegenwoordigt en address het adres is van de socket die de data verzendt.
Zie de functie
recv()voor een uitleg van het optionele flags-argument.
- setsockopt(level: int, optname: int, value: int | bytes) None¶
Stel de waarde van de gegeven socketoptie in. De benodigde symbolische constanten zijn gedefinieerd in de socket-module (SO_* enz.). De value kan een geheel getal of een bytes-achtig object zijn dat een buffer vertegenwoordigt.
- settimeout(value: float | None) None¶
Stel een time-out in voor blokkerende socketbewerkingen. Het value-argument kan een niet-negatief drijvendekommagetal zijn dat seconden uitdrukt, of None. Als een waarde ongelijk aan nul wordt opgegeven, zullen volgende socketbewerkingen een
OSError-uitzondering veroorzaken als de time-outperiode is verstreken voordat de bewerking is voltooid. Als nul wordt opgegeven, wordt de socket in niet-blokkerende modus geplaatst. Als None wordt opgegeven, wordt de socket in blokkerende modus geplaatst.Een draagbaar en generiek alternatief is het gebruik van een
select.poll-object. Hiermee kun je op meerdere objecten tegelijk wachten (en niet alleen op sockets, maar op generieke stream-objecten die polling ondersteunen). Voorbeeld:# 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
Verschil met CPython
CPython veroorzaakt een
socket.timeout-uitzondering in geval van een time-out, wat een subklasse vanOSErroris. MicroPython veroorzaakt in plaats daarvan rechtstreeks een OSError. Als jeexcept OSError:gebruikt om de uitzondering op te vangen, werkt je code zowel in MicroPython als CPython.
- setblocking(flag: bool) None¶
Stel de blokkerende of niet-blokkerende modus van de socket in: als flag onwaar is, wordt de socket op niet-blokkerend gezet, anders op blokkerende modus.
Deze methode is een afkorting voor bepaalde
settimeout()-aanroepen:sock.setblocking(True)is equivalent aansock.settimeout(None)sock.setblocking(False)is equivalent aansock.settimeout(0)
- makefile(mode: str = 'rb', buffering: int = 0, /) Any¶
Retourneer een bestandsobject dat aan de socket is gekoppeld. Het exacte geretourneerde type hangt af van de argumenten die aan makefile() zijn gegeven. De ondersteuning is beperkt tot alleen binaire modi (‘rb’, ‘wb’ en ‘rwb’). De CPython-argumenten encoding, errors en newline worden niet ondersteund.
Verschil met CPython
Aangezien MicroPython geen gebufferde streams ondersteunt, wordt de waarde van de buffering-parameter genegeerd en behandeld alsof deze 0 (ongebufferd) was.
Verschil met CPython
Het sluiten van het bestandsobject dat door makefile() wordt geretourneerd, ZAL ook de oorspronkelijke socket sluiten.
- read(size: int | None = None) bytes¶
Lees maximaal size bytes van de socket. Retourneer een bytes-object. Als size niet is opgegeven, leest het alle beschikbare data van de socket tot EOF; als zodanig keert de methode pas terug wanneer de socket is gesloten. Deze functie probeert zoveel data te lezen als gevraagd (geen “short reads”). Dit is echter mogelijk niet haalbaar bij een niet-blokkerende socket, en dan wordt er minder data geretourneerd.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Lees bytes in buf. Als nbytes is opgegeven, lees dan maximaal dat aantal bytes. Anders lees je maximaal len(buf) bytes. Net als
read()volgt deze methode het “geen short reads”-beleid.Retourwaarde: het aantal bytes dat is gelezen en opgeslagen in buf.
- write(buf: bytes) int¶
Schrijf de buffer van bytes naar de socket. Deze functie zal proberen alle data naar een socket te schrijven (geen “short writes”). Dit is echter mogelijk niet haalbaar bij een niet-blokkerende socket, en de geretourneerde waarde zal kleiner zijn dan de lengte van buf.
Retourwaarde: het aantal geschreven bytes.