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 a getaddrinfo() 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 a getaddrinfo() 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 socket fü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.gaierror kivételt vált ki ennél a függvénynél (az OSError alosztálya). A MicroPython-nak nincs socket.gaierror kivétele, és közvetlenül OSError-t vált ki. Vegye figyelembe, hogy a getaddrinfo() hibaszámai külön névteret alkotnak, és előfordulhat, hogy nem egyeznek meg az errno modul hibaszámaival. A getaddrinfo() 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ételobjektum e.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.

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

Egy adott af címcsaládú bin_addr bináris hálózati cím átalakítása szöveges ábrázolássá:

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

Egy adott af címcsaládú txt_addr szöveges hálózati cím átalakítása bináris ábrázolássá:

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

Konstansok

socket.AF_INET: int

IPv4 címcsalád.

socket.AF_INET6: int

IPv6 címcsalád.

socket.SOCK_STREAM: int

Adatfolyam (TCP) socket-típus.

socket.SOCK_DGRAM: int

Datagram (UDP) socket-típus.

socket.SOCK_RAW: int

Nyers (raw) socket-típus.

socket.IPPROTO_IP: int

Az IP protokollszint. A setsockopt() metódus level argumentumaként használatos az IP_* opciókkal együtt.

socket.IPPROTO_TCP: int

A TCP protokoll. Ezt nem kell átadnia a socket függvénynek (a SOCK_STREAM socket-típus automatikusan kiválasztja); egyetlen valós felhasználása a setsockopt() metódus level argumentumaként van a TCP_* opciókkal együtt.

socket.SOL_SOCKET: int

A socket-opció szintje. A setsockopt() metódus level argumentumaként használatos az SO_* 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_BROADCAST: int

Engedélyezi a datagramok küldését broadcast címre.

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_IP szintű setsockopt() opció.

socket.IP_DROP_MEMBERSHIP: int

Kilépés egy multicast csoportból. Egy IPPROTO_IP szintű setsockopt() opció.

socket.TCP_NODELAY: int

A Nagle-algoritmus letiltása. Egy IPPROTO_TCP szintű 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.

bind(address: Any) None

A socket hozzákötése az address címhez. A socket még nem lehet hozzákötve.

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.

connect(address: Any) None

Csatlakozás egy távoli sockethez az address címen.

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 OSError kivé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.poll objektum 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.timeout kivételt vált ki, amely az OSError alosztálya. A MicroPython ehelyett közvetlenül OSError-t vált ki. Ha az except 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ű a sock.settimeout(None) hívással

  • A sock.setblocking(False) egyenértékű a sock.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.

readline() bytes

Egy sor olvasása, amely sortörés karakterrel végződik.

Visszatérési érték: a beolvasott sor.

write(buf: bytes) int

A bájtpuffer kiírása a socketre. Ez a függvény megpróbálja az összes adatot kiírni egy socketre (nincs „rövid írás”). Ez azonban nem blokkoló socket esetén nem lehetséges, és a visszaadott érték kisebb lesz a buf hosszánál.

Visszatérési érték: a kiírt bájtok száma.

Megjegyzés

A MicroPython nem valósítja meg a socket.error kivételt. A CPython-nak van egy elavult socket.error kivétele, amely az OSError álneve; a MicroPython-ban közvetlenül az OSError kivételt használja a socket-kel kapcsolatos hibák elkapásához.