socket — socket modul¶
Ez a modul hozzáférést biztosít a BSD socket interfészhez.
Eltérés a CPython-tól
A hatékonyság és a konzisztencia érdekében a MicroPython socket objektumai közvetlenül megvalósítanak egy stream (fájlszerű) interfészt. A CPython-ban egy socketet fájlszerű objektummá kell alakítania a makefile() metódussal. Ezt a metódust a MicroPython továbbra is támogatja (de nem csinál semmit), így ahol a CPython-kompatibilitás számít, mindenképpen használja.
Socket-címformátum(ok)¶
A socket modul natív socket-címformátuma egy átlátszatlan adattípus, amelyet a getaddrinfo() függvény ad vissza, és amelyet a szöveges címek (beleértve a numerikus címeket is) feloldásához kell használni:
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)
A getaddrinfo() használata a leghatékonyabb (mind memória, mind feldolgozási teljesítmény szempontjából) és leghordozhatóbb módja a címekkel való munkának.
A socket modul biztosít egy CPython-kompatibilis módot is a címek megadására tuple-ök segítségével, az alább leírtak szerint. Az OpenMV Cam eszközön a socket modul beépített; a numerikus címek közvetlenül megadhatók a tuple-formátumban, de a domainneveket először fel kell oldani a getaddrinfo() függvénnyel.
Összefoglalva:
A gazdagépnevek feloldásához mindig használja a
getaddrinfo()függvényt.Az alább leírt tuple-címek a numerikus címek rövidítéseként használhatók gyors megoldásokhoz és interaktív használathoz.
Tuple-címformátum a socket modulhoz:
IPv4: (ipv4_address, port), ahol az ipv4_address egy pont-jelöléses numerikus IPv4-címet tartalmazó karakterlánc, pl.
"8.8.8.8", a port pedig egy egész portszám az 1-65535 tartományban. A domainnevek nem fogadhatók el ipv4_address értékként; először oldja fel őket agetaddrinfo()függvénnyel.IPv6: (ipv6_address, port, flowinfo, scopeid), ahol az ipv6_address egy kettőspont-jelöléses numerikus IPv6-címet tartalmazó karakterlánc, pl.
"2001:db8::1", a port pedig egy egész portszám az 1-65535 tartományban. A flowinfo értékének 0-nak kell lennie. A scopeid a link-local címek interfész-hatóköri azonosítója. A domainnevek nem fogadhatók el ipv6_address értékként; először oldja fel őket agetaddrinfo()függvénnyel.
Függvények¶
- socket.getaddrinfo(host: str, port: int, af: int = 0, type: int = 0, proto: int = 0, flags: int = 0, /) List[Tuple]¶
Lefordítja a gazdagép/port argumentumot 5-tuple-ök sorozatává, amelyek minden szükséges argumentumot tartalmaznak egy az adott szolgáltatáshoz csatlakozó socket létrehozásához. Az af, type és proto argumentumok (amelyeknek ugyanaz a jelentése, mint a
socketfüggvénynél) használhatók annak szűrésére, hogy milyen típusú címek kerüljenek visszaadásra. Ha egy paraméter nincs megadva, vagy nulla, akkor a címek minden kombinációja visszaadható (a felhasználói oldalon történő szűrést igényelve).Az eredményül kapott 5-tuple-ök listája a következő szerkezetű:
(family, type, proto, canonname, sockaddr)A következő példa megmutatja, hogyan lehet csatlakozni egy adott URL-hez:
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])
A szűrőparaméterek ajánlott használata:
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])
Eltérés a CPython-tól
A CPython hiba esetén
socket.gaierrorkivételt vált ki ennél a függvénynél (azOSErroralosztálya). A MicroPython-nak nincssocket.gaierrorkivétele, és közvetlenül OSError-t vált ki. Vegye figyelembe, hogy agetaddrinfo()hibaszámai külön névteret alkotnak, és előfordulhat, hogy nem egyeznek meg azerrnomodul hibaszámaival. Agetaddrinfo()hibák megkülönböztetése érdekében azokat negatív számok ábrázolják, míg a szabványos rendszerhibák pozitív számok (a hibaszámok egy kivételobjektume.args[0]tulajdonságán keresztül érhetők el). A negatív értékek használata egy ideiglenes részlet, amely a jövőben változhat.
Konstansok¶
- socket.IPPROTO_IP: int¶
Az IP protokollszint. A
setsockopt()metódus level argumentumaként használatos azIP_*opciókkal együtt.
- socket.IPPROTO_TCP: int¶
A TCP protokoll. Ezt nem kell átadnia a
socketfüggvénynek (aSOCK_STREAMsocket-típus automatikusan kiválasztja); egyetlen valós felhasználása asetsockopt()metódus level argumentumaként van aTCP_*opciókkal együtt.
- socket.SOL_SOCKET: int¶
A socket-opció szintje. A
setsockopt()metódus level argumentumaként használatos azSO_*opciókkal együtt.
- socket.SO_REUSEADDR: int¶
Lehetővé teszi a socket számára, hogy olyan címhez/porthoz kötődjön, amely még
TIME_WAITállapotban van.
- socket.SO_KEEPALIVE: int¶
Engedélyezi a keep-alive próbák periodikus küldését egy csatlakoztatott socketen.
- socket.SO_SNDTIMEO: int¶
Küldési időkorlát, ezredmásodpercben, a
setsockopt()metódus value argumentumaként átadva.
- socket.SO_RCVTIMEO: int¶
Fogadási időkorlát, ezredmásodpercben, a
setsockopt()metódus value argumentumaként átadva.
- socket.IP_ADD_MEMBERSHIP: int¶
Csatlakozás egy multicast csoporthoz. Egy
IPPROTO_IPszintűsetsockopt()opció.
- socket.IP_DROP_MEMBERSHIP: int¶
Kilépés egy multicast csoportból. Egy
IPPROTO_IPszintűsetsockopt()opció.
- socket.TCP_NODELAY: int¶
A Nagle-algoritmus letiltása. Egy
IPPROTO_TCPszintűsetsockopt()opció.
- socket.MSG_PEEK: int¶
A
recv()/recvfrom()metódusokhoz: az adatok visszaadása anélkül, hogy eltávolítaná őket a bemeneti sorból.
- socket.MSG_DONTWAIT: int¶
A
recv()/recvfrom()metódusokhoz: a művelet végrehajtása nem blokkoló módban.
Osztályok¶
- class socket.socket(af: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP, /)¶
Egy új socket létrehozása az adott címcsaláddal, socket-típussal és protokollszámmal. A proto megadása a legtöbb esetben nem szükséges (és nem ajánlott); a type argumentum automatikusan kiválasztja a szükséges protokollt:
# Create STREAM TCP socket socket(AF_INET, SOCK_STREAM) # Create DGRAM UDP socket socket(AF_INET, SOCK_DGRAM)
- close() None¶
Megjelöli a socketet lezártként, és felszabadít minden erőforrást. Miután ez megtörténik, a socket objektumon végzett minden jövőbeli művelet sikertelen lesz. A távoli vég EOF jelzést kap, ha a protokoll támogatja.
A socketek automatikusan lezáródnak, amikor a szemétgyűjtő begyűjti őket, de ajánlott explicit módon lezárni őket a
close()metódussal, amint befejezte a velük való munkát.
- listen(backlog: int = 2) None¶
Lehetővé teszi egy szerver számára a kapcsolatok elfogadását. Ha a backlog meg van adva, akkor legalább 0-nak kell lennie (ha alacsonyabb, akkor 0-ra lesz állítva); és megadja azoknak az el nem fogadott kapcsolatoknak a számát, amelyeket a rendszer engedélyez, mielőtt új kapcsolatokat utasítana el. Ha nincs megadva, egy ésszerű alapértelmezett érték kerül kiválasztásra.
- accept() Tuple['socket', Tuple]¶
Egy kapcsolat elfogadása. A socketnek egy címhez kell kötve lennie és kapcsolatokra kell figyelnie. A visszatérési érték egy (conn, address) pár, ahol a conn egy új socket objektum, amely a kapcsolaton adatok küldésére és fogadására használható, az address pedig a socket másik végéhez kötött cím.
- send(bytes: bytes) int¶
Adatok küldése a socketre. A socketnek csatlakoztatva kell lennie egy távoli sockethez. Visszaadja az elküldött bájtok számát, amely kisebb lehet az adatok hosszánál („rövid írás”).
- sendall(bytes: bytes) None¶
Minden adat elküldése a socketre. A socketnek csatlakoztatva kell lennie egy távoli sockethez. A
send()metódussal ellentétben ez a metódus megpróbálja az összes adatot elküldeni, az adatokat darabonként, egymás után küldve.Ennek a metódusnak a viselkedése nem blokkoló socketeken nincs definiálva. Emiatt a MicroPython-ban ajánlott helyette a
write()metódust használni, amely ugyanazt a „nincs rövid írás” elvet követi blokkoló socketek esetén, és visszaadja az elküldött bájtok számát nem blokkoló socketek esetén.
- recv(bufsize: int, flags: int = 0) bytes¶
Adatok fogadása a socketről. A visszatérési érték egy bytes objektum, amely a fogadott adatokat reprezentálja. Az egyszerre fogadható adatok maximális mennyiségét a bufsize határozza meg.
Az opcionális flags argumentum az üzenetjelzők (
MSG_PEEK,MSG_DONTWAIT) bitenkénti VAGY kapcsolata, amelyeknek ugyanaz a jelentése, mint a CPython-ban.
- sendto(bytes: bytes, address: Any) int¶
Adatok küldése a socketre. A socketnek nem szabad csatlakoztatva lennie egy távoli sockethez, mivel a cél-socketet az address határozza meg.
- recvfrom(bufsize: int, flags: int = 0) Tuple[bytes, Tuple]¶
Adatok fogadása a socketről. A visszatérési érték egy (bytes, address) pár, ahol a bytes egy bytes objektum, amely a fogadott adatokat reprezentálja, az address pedig az adatokat küldő socket címe.
Az opcionális flags argumentum magyarázatát lásd a
recv()függvénynél.
- setsockopt(level: int, optname: int, value: int | bytes) None¶
Az adott socket-opció értékének beállítása. A szükséges szimbolikus konstansok a socket modulban vannak definiálva (SO_* stb.). A value lehet egész szám vagy egy puffert reprezentáló bytes-szerű objektum.
- settimeout(value: float | None) None¶
Időkorlát beállítása a blokkoló socket-műveletekhez. A value argumentum lehet egy nemnegatív lebegőpontos szám, amely másodpercekben fejezi ki az értéket, vagy None. Ha nem nulla értéket adnak meg, a későbbi socket-műveletek
OSErrorkivételt váltanak ki, ha az időkorlát-időtartam letelt, mielőtt a művelet befejeződött volna. Ha nullát adnak meg, a socket nem blokkoló módba kerül. Ha None értéket adnak meg, a socket blokkoló módba kerül.Egy hordozható és általános alternatíva egy
select.pollobjektum használata. Ez lehetővé teszi több objektumra való egyidejű várakozást (és nem csak socketekre, hanem általános stream objektumokra, amelyek támogatják a lekérdezést). Példa:# 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
Eltérés a CPython-tól
A CPython időtúllépés esetén
socket.timeoutkivételt vált ki, amely azOSErroralosztálya. A MicroPython ehelyett közvetlenül OSError-t vált ki. Ha azexcept OSError:szerkezetet használja a kivétel elkapására, a kódja mind a MicroPython-ban, mind a CPython-ban működni fog.
- setblocking(flag: bool) None¶
A socket blokkoló vagy nem blokkoló módjának beállítása: ha a flag hamis, a socket nem blokkoló módba kerül, egyébként blokkoló módba.
Ez a metódus bizonyos
settimeout()hívások rövidítése:A
sock.setblocking(True)egyenértékű asock.settimeout(None)hívássalA
sock.setblocking(False)egyenértékű asock.settimeout(0)hívással
- makefile(mode: str = 'rb', buffering: int = 0, /) Any¶
Egy a sockethez társított fájlobjektum visszaadása. A pontos visszaadott típus a makefile() metódusnak átadott argumentumoktól függ. A támogatás csak a bináris módokra korlátozódik («rb», «wb» és «rwb»). A CPython argumentumai: encoding, errors és newline nem támogatottak.
Eltérés a CPython-tól
Mivel a MicroPython nem támogatja a pufferelt adatfolyamokat, a buffering paraméter értékei figyelmen kívül maradnak, és úgy kezelődnek, mintha 0 lenne (pufferelés nélkül).
Eltérés a CPython-tól
A makefile() által visszaadott fájlobjektum lezárása az eredeti socketet IS le fogja zárni.
- read(size: int | None = None) bytes¶
Legfeljebb size bájt olvasása a socketről. Visszaad egy bytes objektumot. Ha a size nincs megadva, akkor minden a socketről elérhető adatot beolvas EOF-ig; ennek megfelelően a metódus addig nem tér vissza, amíg a socket le nem zárul. Ez a függvény annyi adatot próbál olvasni, amennyit kértek (nincs „rövid olvasás”). Ez azonban nem blokkoló socket esetén nem lehetséges, és akkor kevesebb adat kerül visszaadásra.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Bájtok olvasása a buf pufferbe. Ha az nbytes meg van adva, akkor legfeljebb annyi bájtot olvas. Ellenkező esetben legfeljebb len(buf) bájtot olvas. A
read()metódushoz hasonlóan ez a metódus is a „nincs rövid olvasás” elvet követi.Visszatérési érték: a beolvasott és a buf pufferbe tárolt bájtok száma.