socket — modul socket¶
Tento modul poskytuje přístup k rozhraní BSD socketů.
Rozdíl oproti CPythonu
Z důvodu efektivity a konzistence implementují objekty socketů v MicroPythonu rozhraní stream (souboru podobné) přímo. V CPythonu je nutné převést socket na objekt podobný souboru pomocí metody makefile(). Tato metoda je v MicroPythonu stále podporována (ale je no-op), takže tam, kde záleží na kompatibilitě s CPythonem, ji určitě používejte.
Formát(y) adresy socketu¶
Nativní formát adresy socketu modulu socket je neprůhledný datový typ vracený funkcí getaddrinfo(), kterou je nutné použít k rozlišení textové adresy (včetně numerických adres):
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)
Použití getaddrinfo() je nejefektivnější (jak z hlediska paměti, tak výpočetního výkonu) a přenositelný způsob práce s adresami.
Modul socket rovněž poskytuje způsob kompatibilní s CPythonem pro zadávání adres pomocí n-tic, jak je popsáno níže. Na OpenMV Cam je modul socket zabudovaný; numerické adresy lze zadat přímo ve formátu n-tice, ale doménová jména musí být nejprve rozlišena pomocí getaddrinfo().
Shrnutí:
Pro rozlišení názvů hostitelů vždy používejte
getaddrinfo().Adresy ve formátu n-tice popsané níže lze použít jako zkratku pro numerické adresy, pro rychlé hacky a interaktivní použití.
Formát adresy ve formátu n-tice pro modul socket:
IPv4: (ipv4_address, port), kde ipv4_address je řetězec s numerickou IPv4 adresou v tečkové notaci, např.
"8.8.8.8", a port je celočíselné číslo portu v rozsahu 1-65535. Doménová jména nejsou jako ipv4_address přijímána; nejprve je rozlište pomocígetaddrinfo().IPv6: (ipv6_address, port, flowinfo, scopeid), kde ipv6_address je řetězec s numerickou IPv6 adresou v dvojtečkové notaci, např.
"2001:db8::1", a port je celočíselné číslo portu v rozsahu 1-65535. flowinfo musí být 0. scopeid je identifikátor rozsahu rozhraní pro link-local adresy. Doménová jména nejsou jako ipv6_address přijímána; nejprve je rozlište pomocígetaddrinfo().
Funkce¶
- socket.getaddrinfo(host: str, port: int, af: int = 0, type: int = 0, proto: int = 0, flags: int = 0, /) List[Tuple]¶
Přeloží argument host/port na sekvenci 5-tic, které obsahují všechny argumenty potřebné pro vytvoření socketu připojeného k dané službě. Argumenty af, type a proto (které mají stejný význam jako u funkce
socket) lze použít k filtrování, jaký druh adres je vracen. Pokud parametr není zadán nebo je nulový, mohou být vraceny všechny kombinace adres (vyžadující filtrování na straně uživatele).Výsledný seznam 5-tic má následující strukturu:
(family, type, proto, canonname, sockaddr)Následující příklad ukazuje, jak se připojit k dané 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])
Doporučené použití filtrovacích parametrů:
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])
Rozdíl oproti CPythonu
CPython vyvolá v případě chyby v této funkci výjimku
socket.gaierror(podtříduOSError). MicroPython nemásocket.gaierrora vyvolá přímo OSError. Pozor, čísla chyb funkcegetaddrinfo()tvoří samostatný jmenný prostor a nemusí odpovídat číslům chyb z moduluerrno. K odlišení chybgetaddrinfo()jsou tyto reprezentovány zápornými čísly, zatímco standardní systémové chyby jsou čísla kladná (čísla chyb jsou dostupná pomocí vlastnostie.args[0]z objektu výjimky). Použití záporných hodnot je prozatímní detail, který se v budoucnu může změnit.
Konstanty¶
- socket.IPPROTO_IP: int¶
Úroveň protokolu IP. Používá se jako argument level metody
setsockopt()společně s volbamiIP_*.
- socket.IPPROTO_TCP: int¶
Protokol TCP. Není nutné jej předávat do
socket(typ socketuSOCK_STREAMjej vybere automaticky); jeho jediné skutečné využití je jako argument level metodysetsockopt()společně s volbamiTCP_*.
- socket.SOL_SOCKET: int¶
Úroveň voleb socketu. Používá se jako argument level metody
setsockopt()společně s volbamiSO_*.
- socket.SO_REUSEADDR: int¶
Umožní socketu navázat se na adresu/port, který je stále ve stavu
TIME_WAIT.
- socket.SO_SNDTIMEO: int¶
Časový limit odesílání v milisekundách, předaný jako argument value metodě
setsockopt().
- socket.SO_RCVTIMEO: int¶
Časový limit příjmu v milisekundách, předaný jako argument value metodě
setsockopt().
- socket.IP_ADD_MEMBERSHIP: int¶
Připojí se k multicastové skupině. Volba
setsockopt()úrovněIPPROTO_IP.
- socket.IP_DROP_MEMBERSHIP: int¶
Opustí multicastovou skupinu. Volba
setsockopt()úrovněIPPROTO_IP.
- socket.TCP_NODELAY: int¶
Zakáže Nagleho algoritmus. Volba
setsockopt()úrovněIPPROTO_TCP.
- socket.MSG_PEEK: int¶
Pro
recv()/recvfrom(): vrátí data bez jejich odstranění ze vstupní fronty.
- socket.MSG_DONTWAIT: int¶
Pro
recv()/recvfrom(): provede operaci v neblokujícím režimu.
Třídy¶
- class socket.socket(af: int = AF_INET, type: int = SOCK_STREAM, proto: int = IPPROTO_TCP, /)¶
Vytvoří nový socket s použitím dané adresní rodiny, typu socketu a čísla protokolu. Zadání proto ve většině případů není vyžadováno (a není doporučováno); argument type vybere potřebný protokol automaticky:
# Create STREAM TCP socket socket(AF_INET, SOCK_STREAM) # Create DGRAM UDP socket socket(AF_INET, SOCK_DGRAM)
- close() None¶
Označí socket jako uzavřený a uvolní všechny prostředky. Jakmile k tomu dojde, všechny budoucí operace s objektem socketu selžou. Vzdálený konec obdrží indikaci EOF, pokud to protokol podporuje.
Sockety jsou automaticky uzavírány při garbage collection, ale doporučuje se
close()je explicitně, jakmile s nimi dokončíte práci.
- listen(backlog: int = 2) None¶
Umožní serveru přijímat připojení. Pokud je zadán backlog, musí být alespoň 0 (pokud je nižší, bude nastaven na 0); a určuje počet nepřijatých připojení, který systém povolí před odmítnutím nových připojení. Pokud není zadán, je zvolena výchozí rozumná hodnota.
- accept() Tuple['socket', Tuple]¶
Přijme připojení. Socket musí být navázán na adresu a naslouchat připojením. Návratovou hodnotou je dvojice (conn, address), kde conn je nový objekt socketu použitelný pro odesílání a příjem dat na tomto připojení a address je adresa navázaná na socket na druhém konci připojení.
- send(bytes: bytes) int¶
Odešle data na socket. Socket musí být připojen ke vzdálenému socketu. Vrací počet odeslaných bajtů, který může být menší než délka dat („short write“).
- sendall(bytes: bytes) None¶
Odešle všechna data na socket. Socket musí být připojen ke vzdálenému socketu. Na rozdíl od
send()se tato metoda pokusí odeslat všechna data tím, že je odesílá postupně po částech.Chování této metody na neblokujících socketech není definováno. Z tohoto důvodu se v MicroPythonu doporučuje místo toho používat metodu
write(), která má stejnou politiku „no short writes“ pro blokující sockety a u neblokujících socketů vrátí počet odeslaných bajtů.
- recv(bufsize: int, flags: int = 0) bytes¶
Přijme data ze socketu. Návratovou hodnotou je objekt typu bytes reprezentující přijatá data. Maximální množství dat přijatých najednou je určeno parametrem bufsize.
Volitelný argument flags je bitový OR příznaků zprávy (
MSG_PEEK,MSG_DONTWAIT), které mají stejný význam jako v CPythonu.
- sendto(bytes: bytes, address: Any) int¶
Odešle data na socket. Socket by neměl být připojen ke vzdálenému socketu, protože cílový socket je určen parametrem address.
- recvfrom(bufsize: int, flags: int = 0) Tuple[bytes, Tuple]¶
Přijme data ze socketu. Návratovou hodnotou je dvojice (bytes, address), kde bytes je objekt typu bytes reprezentující přijatá data a address je adresa socketu odesílajícího data.
Vysvětlení volitelného argumentu flags viz funkce
recv().
- setsockopt(level: int, optname: int, value: int | bytes) None¶
Nastaví hodnotu dané volby socketu. Potřebné symbolické konstanty jsou definovány v modulu socket (SO_* atd.). value může být celé číslo nebo objekt podobný bytes reprezentující buffer.
- settimeout(value: float | None) None¶
Nastaví časový limit pro blokující operace socketu. Argument value může být nezáporné desetinné číslo vyjadřující sekundy, nebo None. Pokud je zadána nenulová hodnota, následující operace socketu vyvolají výjimku
OSError, pokud hodnota časového limitu uplyne dříve, než byla operace dokončena. Pokud je zadána nula, socket je uveden do neblokujícího režimu. Pokud je zadáno None, socket je uveden do blokujícího režimu.Přenositelnou a obecnou alternativou je použít objekt
select.poll. To umožňuje čekat na více objektů současně (a nejen na sockety, ale na obecné objekty stream, které podporují polling). Příklad:# 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
Rozdíl oproti CPythonu
CPython vyvolá v případě vypršení časového limitu výjimku
socket.timeout, která je podtřídouOSError. MicroPython místo toho vyvolá přímo OSError. Pokud k zachycení výjimky použijeteexcept OSError:, váš kód bude fungovat v MicroPythonu i v CPythonu.
- setblocking(flag: bool) None¶
Nastaví blokující nebo neblokující režim socketu: pokud je flag false, socket je nastaven na neblokující, jinak na blokující režim.
Tato metoda je zkratkou pro určitá volání
settimeout():sock.setblocking(True)je ekvivalentnísock.settimeout(None)sock.setblocking(False)je ekvivalentnísock.settimeout(0)
- makefile(mode: str = 'rb', buffering: int = 0, /) Any¶
Vrátí objekt souboru asociovaný se socketem. Přesný vrácený typ závisí na argumentech předaných do makefile(). Podpora je omezena pouze na binární režimy (‚rb‘, ‚wb‘ a ‚rwb‘). Argumenty CPythonu encoding, errors a newline nejsou podporovány.
Rozdíl oproti CPythonu
Protože MicroPython nepodporuje bufferované streamy, hodnota parametru buffering je ignorována a považována za 0 (bez bufferování).
Rozdíl oproti CPythonu
Uzavření objektu souboru vráceného metodou makefile() uzavře TAKÉ původní socket.
- read(size: int | None = None) bytes¶
Načte ze socketu až size bajtů. Vrátí objekt typu bytes. Pokud size není zadán, načte všechna data dostupná ze socketu až do EOF; jako taková se metoda nevrátí, dokud není socket uzavřen. Tato funkce se pokusí načíst tolik dat, kolik je požadováno (žádné „short reads“). U neblokujícího socketu to však nemusí být možné, a pak bude vráceno méně dat.
- readinto(buf: bytearray | memoryview, nbytes: int | None = None) int¶
Načte bajty do buf. Pokud je zadán nbytes, načte nanejvýš tolik bajtů. Jinak načte nanejvýš len(buf) bajtů. Stejně jako
read()se tato metoda řídí politikou „no short reads“.Návratová hodnota: počet bajtů načtených a uložených do buf.