socket — socket-modul

Denna modul ger åtkomst till BSD-socketgränssnittet.

Skillnad mot CPython

För effektivitet och konsekvens implementerar socketobjekt i MicroPython ett stream-gränssnitt (fillikt) direkt. I CPython behöver du konvertera en socket till ett fillikt objekt med metoden makefile(). Denna metod stöds fortfarande av MicroPython (men gör ingenting), så där kompatibilitet med CPython är viktig bör du se till att använda den.

Socketadressformat

Det inbyggda socketadressformatet i socket-modulen är en ogenomskinlig datatyp som returneras av funktionen getaddrinfo(), vilken måste användas för att lösa upp textuella adresser (inklusive numeriska adresser):

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)

Att använda getaddrinfo() är det mest effektiva (både vad gäller minne och processorkraft) och portabla sättet att arbeta med adresser.

socket-modulen tillhandahåller också ett CPython-kompatibelt sätt att ange adresser med tupler, som beskrivs nedan. På OpenMV Cam är socket-modulen inbyggd; numeriska adresser kan anges direkt i tupelformatet, men domännamn måste först lösas upp med getaddrinfo().

Sammanfattningsvis:

  • Använd alltid getaddrinfo() för att lösa upp värdnamn.

  • Tupeladresser som beskrivs nedan kan användas som en genväg för numeriska adresser, för snabba lösningar och interaktiv användning.

Tupeladressformat för socket-modulen:

  • IPv4: (ipv4_address, port), där ipv4_address är en sträng med en numerisk IPv4-adress i punktnotation, t.ex. "8.8.8.8", och port är ett heltal som anger portnummer i intervallet 1-65535. Domännamn accepteras inte som ipv4_address; lös upp dem först med getaddrinfo().

  • IPv6: (ipv6_address, port, flowinfo, scopeid), där ipv6_address är en sträng med en numerisk IPv6-adress i kolonnotation, t.ex. "2001:db8::1", och port är ett heltal som anger portnummer i intervallet 1-65535. flowinfo måste vara 0. scopeid är gränssnittets scope-identifierare för länklokala adresser. Domännamn accepteras inte som ipv6_address; lös upp dem först med getaddrinfo().

Funktioner

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

Översätt argumentet host/port till en sekvens av 5-tupler som innehåller alla nödvändiga argument för att skapa en socket ansluten till den tjänsten. Argumenten af, type och proto (som har samma betydelse som för funktionen socket) kan användas för att filtrera vilken sorts adresser som returneras. Om en parameter inte anges eller är noll kan alla kombinationer av adresser returneras (vilket kräver filtrering på användarsidan).

Den resulterande listan av 5-tupler har följande struktur:

(family, type, proto, canonname, sockaddr)

Följande exempel visar hur man ansluter till en given 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])

Rekommenderad användning av filtreringsparametrar:

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])

Skillnad mot CPython

CPython ger upphov till undantaget socket.gaierror (en underklass till OSError) vid fel i denna funktion. MicroPython har inte socket.gaierror och ger upphov till OSError direkt. Observera att felnummer från getaddrinfo() bildar en separat namnrymd och kanske inte matchar felnummer från modulen errno. För att skilja ut getaddrinfo()-fel representeras de av negativa tal, medan vanliga systemfel är positiva tal (felnummer är åtkomliga via egenskapen e.args[0] på ett undantagsobjekt). Användningen av negativa värden är en provisorisk detalj som kan komma att ändras i framtiden.

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

Konvertera en binär nätverksadress bin_addr för den givna adressfamiljen af till en textuell representation:

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

Konvertera en textuell nätverksadress txt_addr för den givna adressfamiljen af till en binär representation:

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

Konstanter

socket.AF_INET: int

IPv4-adressfamilj.

socket.AF_INET6: int

IPv6-adressfamilj.

socket.SOCK_STREAM: int

Sockettyp för ström (TCP).

socket.SOCK_DGRAM: int

Sockettyp för datagram (UDP).

socket.SOCK_RAW: int

Rå sockettyp.

socket.IPPROTO_IP: int

IP-protokollnivån. Används som argumentet level till setsockopt() tillsammans med IP_*-alternativen.

socket.IPPROTO_TCP: int

TCP-protokollet. Du behöver inte skicka detta till socket (sockettypen SOCK_STREAM väljer det automatiskt); dess enda verkliga användning är som argumentet level till setsockopt() tillsammans med TCP_*-alternativen.

socket.SOL_SOCKET: int

Socketalternativnivån. Används som argumentet level till setsockopt() tillsammans med SO_*-alternativen.

socket.SO_REUSEADDR: int

Tillåt socketen att bindas till en adress/port som fortfarande är i tillståndet TIME_WAIT.

socket.SO_BROADCAST: int

Tillåt sändning av datagram till en broadcast-adress.

socket.SO_KEEPALIVE: int

Aktivera periodisk sändning av keep-alive-sonder på en ansluten socket.

socket.SO_SNDTIMEO: int

Sändningstimeout, i millisekunder, som skickas som argumentet value till setsockopt().

socket.SO_RCVTIMEO: int

Mottagningstimeout, i millisekunder, som skickas som argumentet value till setsockopt().

socket.IP_ADD_MEMBERSHIP: int

Gå med i en multicastgrupp. Ett setsockopt()-alternativ på IPPROTO_IP-nivå.

socket.IP_DROP_MEMBERSHIP: int

Lämna en multicastgrupp. Ett setsockopt()-alternativ på IPPROTO_IP-nivå.

socket.TCP_NODELAY: int

Inaktivera Nagles algoritm. Ett setsockopt()-alternativ på IPPROTO_TCP-nivå.

socket.MSG_PEEK: int

För recv() / recvfrom(): returnera data utan att ta bort dem från inmatningskön.

socket.MSG_DONTWAIT: int

För recv() / recvfrom(): utför operationen i icke-blockerande läge.

Klasser

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

Skapa en ny socket med den givna adressfamiljen, sockettypen och protokollnumret. Att ange proto är i de flesta fall inte nödvändigt (och inte rekommenderat); argumentet type väljer det nödvändiga protokollet automatiskt:

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

Markera socketen som stängd och frigör alla resurser. När det sker kommer alla framtida operationer på socketobjektet att misslyckas. Fjärränden kommer att få en EOF-indikation om protokollet stöder det.

Sockets stängs automatiskt när de skräpsamlas, men det rekommenderas att close() dem explicit så snart du är klar med dem.

bind(address: Any) None

Bind socketen till address. Socketen får inte redan vara bunden.

listen(backlog: int = 2) None

Gör det möjligt för en server att acceptera anslutningar. Om backlog anges måste det vara minst 0 (om det är lägre sätts det till 0) och anger antalet icke-accepterade anslutningar som systemet tillåter innan nya anslutningar avvisas. Om det inte anges väljs ett rimligt standardvärde.

accept() Tuple['socket', Tuple]

Acceptera en anslutning. Socketen måste vara bunden till en adress och lyssna efter anslutningar. Returvärdet är ett par (conn, address) där conn är ett nytt socketobjekt som kan användas för att skicka och ta emot data på anslutningen, och address är den adress som är bunden till socketen i den andra änden av anslutningen.

connect(address: Any) None

Anslut till en fjärrsocket på address.

send(bytes: bytes) int

Skicka data till socketen. Socketen måste vara ansluten till en fjärrsocket. Returnerar antalet skickade byte, vilket kan vara mindre än längden på data (”short write”).

sendall(bytes: bytes) None

Skicka all data till socketen. Socketen måste vara ansluten till en fjärrsocket. Till skillnad från send() försöker denna metod skicka all data, genom att skicka data bit för bit i följd.

Beteendet hos denna metod på icke-blockerande sockets är odefinierat. På grund av detta rekommenderas det i MicroPython att i stället använda metoden write(), som har samma ”inga short writes”-policy för blockerande sockets och returnerar antalet skickade byte på icke-blockerande sockets.

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

Ta emot data från socketen. Returvärdet är ett bytes-objekt som representerar de mottagna data. Den maximala mängden data som tas emot åt gången anges av bufsize.

Det valfria argumentet flags är en bitvis OR av meddelandeflaggor (MSG_PEEK, MSG_DONTWAIT), vilka har samma betydelse som i CPython.

sendto(bytes: bytes, address: Any) int

Skicka data till socketen. Socketen ska inte vara ansluten till en fjärrsocket, eftersom destinationssocketen anges av address.

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

Ta emot data från socketen. Returvärdet är ett par (bytes, address) där bytes är ett bytes-objekt som representerar de mottagna data och address är adressen till den socket som skickar data.

Se funktionen recv() för en förklaring av det valfria argumentet flags.

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

Ange värdet för det givna socketalternativet. De nödvändiga symboliska konstanterna är definierade i socket-modulen (SO_* m.m.). value kan vara ett heltal eller ett bytesliknande objekt som representerar en buffert.

settimeout(value: float | None) None

Ange en timeout för blockerande socketoperationer. Argumentet value kan vara ett icke-negativt flyttal som uttrycker sekunder, eller None. Om ett värde skilt från noll anges kommer efterföljande socketoperationer att ge upphov till ett OSError-undantag om timeout-perioden har förflutit innan operationen har slutförts. Om noll anges försätts socketen i icke-blockerande läge. Om None anges försätts socketen i blockerande läge.

Ett portabelt och generiskt alternativ är att använda ett select.poll-objekt. Detta gör det möjligt att vänta på flera objekt samtidigt (och inte bara på sockets, utan på generiska stream-objekt som stöder polling). Exempel:

# 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

Skillnad mot CPython

CPython ger upphov till undantaget socket.timeout vid timeout, vilket är en underklass till OSError. MicroPython ger i stället upphov till ett OSError direkt. Om du använder except OSError: för att fånga undantaget kommer din kod att fungera både i MicroPython och CPython.

setblocking(flag: bool) None

Ange blockerande eller icke-blockerande läge för socketen: om flag är falskt sätts socketen till icke-blockerande, annars till blockerande läge.

Denna metod är en förkortning för vissa settimeout()-anrop:

  • sock.setblocking(True) är likvärdigt med sock.settimeout(None)

  • sock.setblocking(False) är likvärdigt med sock.settimeout(0)

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

Returnera ett filobjekt kopplat till socketen. Den exakta returnerade typen beror på argumenten som ges till makefile(). Stödet är begränsat till endast binära lägen (’rb’, ’wb’ och ’rwb’). CPythons argument encoding, errors och newline stöds inte.

Skillnad mot CPython

Eftersom MicroPython inte stöder buffrade strömmar ignoreras värdet på parametern buffering och behandlas som om det vore 0 (obuffrat).

Skillnad mot CPython

Att stänga filobjektet som returneras av makefile() KOMMER att stänga den ursprungliga socketen också.

read(size: int | None = None) bytes

Läs upp till size byte från socketen. Returnera ett bytes-objekt. Om size inte anges läses alla tillgängliga data från socketen tills EOF; metoden returnerar därmed inte förrän socketen är stängd. Denna funktion försöker läsa så mycket data som efterfrågas (inga ”short reads”). Detta kan dock vara omöjligt med en icke-blockerande socket, och då returneras mindre data.

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

Läs byte in i buf. Om nbytes anges läses högst så många byte. Annars läses högst len(buf) byte. Precis som read() följer denna metod policyn ”inga short reads”.

Returvärde: antalet byte som lästs och lagrats i buf.

readline() bytes

Läs en rad, som avslutas med ett radslutstecken.

Returvärde: den lästa raden.

write(buf: bytes) int

Skriv bufferten av byte till socketen. Denna funktion försöker skriva all data till en socket (inga ”short writes”). Detta kan dock vara omöjligt med en icke-blockerande socket, och det returnerade värdet kommer då att vara mindre än längden på buf.

Returvärde: antalet skrivna byte.

Anteckning

MicroPython implementerar inte socket.error. CPython har ett föråldrat socket.error-undantag som är ett alias för OSError; i MicroPython, använd OSError direkt för att fånga socketrelaterade fel.