socket — modul socket

Ovaj modul pruža pristup BSD socket sučelju.

Razlika u odnosu na CPython

Radi učinkovitosti i dosljednosti, socket objekti u MicroPythonu izravno implementiraju stream (datoteci sličan) sučelje. U CPythonu morate pretvoriti socket u datoteci sličan objekt pomoću metode makefile(). Ova metoda i dalje je podržana u MicroPythonu (ali nema učinka), pa gdje je važna kompatibilnost s CPythonom, svakako je upotrijebite.

Format(i) socket adrese

Izvorni format socket adrese modula socket neproziran je tip podataka koji vraća funkcija getaddrinfo(), a koji se mora koristiti za razrješavanje tekstualnih adresa (uključujući numeričke adrese):

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)

Korištenje getaddrinfo() najučinkovitiji je (i u smislu memorije i procesorske snage) i najprenosiviji način rada s adresama.

Modul socket također pruža s CPythonom kompatibilan način navođenja adresa pomoću n-torki, kako je opisano u nastavku. Na OpenMV Cam modul socket ugrađen je; numeričke adrese mogu se zadati izravno u formatu n-torke, ali nazivi domena moraju se prvo razriješiti pomoću getaddrinfo().

Ukratko:

  • Uvijek koristite getaddrinfo() za razrješavanje naziva domaćina.

  • Adrese u obliku n-torke opisane u nastavku mogu se koristiti kao prečac za numeričke adrese, za brze improvizacije i interaktivnu upotrebu.

Format adrese u obliku n-torke za modul socket:

  • IPv4: (ipv4_address, port), gdje je ipv4_address niz znakova s numeričkom IPv4 adresom u notaciji s točkama, npr. "8.8.8.8", a port cijeli broj porta u rasponu 1-65535. Nazivi domena ne prihvaćaju se kao ipv4_address; prvo ih razriješite pomoću getaddrinfo().

  • IPv6: (ipv6_address, port, flowinfo, scopeid), gdje je ipv6_address niz znakova s numeričkom IPv6 adresom u notaciji s dvotočkama, npr. "2001:db8::1", a port cijeli broj porta u rasponu 1-65535. flowinfo mora biti 0. scopeid je identifikator opsega sučelja za adrese lokalne veze. Nazivi domena ne prihvaćaju se kao ipv6_address; prvo ih razriješite pomoću getaddrinfo().

Funkcije

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

Prevodi argument domaćin/port u niz 5-torki koje sadrže sve potrebne argumente za stvaranje socketa povezanog s tom uslugom. Argumenti af, type i proto (koji imaju isto značenje kao za funkciju socket) mogu se koristiti za filtriranje vrste adresa koje se vraćaju. Ako parametar nije naveden ili je nula, mogu se vratiti sve kombinacije adresa (uz potrebu filtriranja na strani korisnika).

Rezultirajući popis 5-torki ima sljedeću strukturu:

(family, type, proto, canonname, sockaddr)

Sljedeći primjer pokazuje kako se povezati s danim url-om:

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

Preporučeno korištenje parametara za filtriranje:

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

Razlika u odnosu na CPython

CPython izaziva iznimku socket.gaierror (podklasa OSError) u slučaju pogreške u ovoj funkciji. MicroPython nema socket.gaierror i izaziva OSError izravno. Imajte na umu da brojevi pogrešaka funkcije getaddrinfo() čine zaseban imenski prostor i možda se ne podudaraju s brojevima pogrešaka iz modula errno. Kako bi se razlikovale pogreške funkcije getaddrinfo(), predstavljene su negativnim brojevima, dok su standardne sistemske pogreške pozitivni brojevi (brojevi pogrešaka dostupni su pomoću svojstva e.args[0] iz objekta iznimke). Korištenje negativnih vrijednosti privremeni je detalj koji se u budućnosti može promijeniti.

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

Pretvara binarnu mrežnu adresu bin_addr dane adresne obitelji af u tekstualnu reprezentaciju:

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

Pretvara tekstualnu mrežnu adresu txt_addr dane adresne obitelji af u binarnu reprezentaciju:

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

Konstante

socket.AF_INET: int

IPv4 adresna obitelj.

socket.AF_INET6: int

IPv6 adresna obitelj.

socket.SOCK_STREAM: int

Tip stream (TCP) socketa.

socket.SOCK_DGRAM: int

Tip datagram (UDP) socketa.

socket.SOCK_RAW: int

Tip neobrađenog (raw) socketa.

socket.IPPROTO_IP: int

Razina IP protokola. Koristi se kao argument level za setsockopt() zajedno s opcijama IP_*.

socket.IPPROTO_TCP: int

TCP protokol. Ne morate ga prosljeđivati socket (tip socketa SOCK_STREAM ga automatski odabire); njegova jedina stvarna upotreba jest kao argument level za setsockopt() zajedno s opcijama TCP_*.

socket.SOL_SOCKET: int

Razina opcija socketa. Koristi se kao argument level za setsockopt() zajedno s opcijama SO_*.

socket.SO_REUSEADDR: int

Dopušta socketu da se veže na adresu/port koji je još u stanju TIME_WAIT.

socket.SO_BROADCAST: int

Dopušta slanje datagrama na broadcast adresu.

socket.SO_KEEPALIVE: int

Omogućuje periodično slanje keep-alive sondi na povezanom socketu.

socket.SO_SNDTIMEO: int

Vremensko ograničenje slanja, u milisekundama, proslijeđeno kao argument value za setsockopt().

socket.SO_RCVTIMEO: int

Vremensko ograničenje primanja, u milisekundama, proslijeđeno kao argument value za setsockopt().

socket.IP_ADD_MEMBERSHIP: int

Pridružuje se multicast grupi. Opcija setsockopt() na razini IPPROTO_IP.

socket.IP_DROP_MEMBERSHIP: int

Napušta multicast grupu. Opcija setsockopt() na razini IPPROTO_IP.

socket.TCP_NODELAY: int

Onemogućuje Nagleov algoritam. Opcija setsockopt() na razini IPPROTO_TCP.

socket.MSG_PEEK: int

Za recv() / recvfrom(): vraća podatke bez njihovog uklanjanja iz ulaznog reda.

socket.MSG_DONTWAIT: int

Za recv() / recvfrom(): izvodi operaciju u neblokirajućem načinu rada.

Klase

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

Stvara novi socket koristeći danu adresnu obitelj, tip socketa i broj protokola. Navođenje proto u većini slučajeva nije potrebno (niti se preporučuje); argument type automatski odabire potrebni protokol:

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

Označava socket zatvorenim i oslobađa sve resurse. Kada se to dogodi, sve buduće operacije na socket objektu neće uspjeti. Udaljeni kraj primit će EOF indikaciju ako je protokol podržava.

Socketi se automatski zatvaraju kada se sakupe kao smeće, ali preporučuje se da ih izričito zatvorite pomoću close() čim završite s radom na njima.

bind(address: Any) None

Veže socket na address. Socket ne smije već biti vezan.

listen(backlog: int = 2) None

Omogućuje poslužitelju prihvaćanje veza. Ako je naveden backlog, mora biti najmanje 0 (ako je manji, postavit će se na 0); određuje broj neprihvaćenih veza koje će sustav dopustiti prije odbijanja novih veza. Ako nije naveden, odabire se razumna zadana vrijednost.

accept() Tuple['socket', Tuple]

Prihvaća vezu. Socket mora biti vezan na adresu i osluškivati veze. Povratna vrijednost je par (conn, address) gdje je conn novi socket objekt koji se može koristiti za slanje i primanje podataka na vezi, a address je adresa vezana na socket na drugom kraju veze.

connect(address: Any) None

Povezuje se s udaljenim socketom na address.

send(bytes: bytes) int

Šalje podatke na socket. Socket mora biti povezan s udaljenim socketom. Vraća broj poslanih bajtova, koji može biti manji od duljine podataka („kratko pisanje”).

sendall(bytes: bytes) None

Šalje sve podatke na socket. Socket mora biti povezan s udaljenim socketom. Za razliku od send(), ova će metoda pokušati poslati sve podatke, šaljući podatke dio po dio uzastopno.

Ponašanje ove metode na neblokirajućim socketima nije definirano. Zbog toga se u MicroPythonu preporučuje umjesto nje koristiti metodu write(), koja ima istu politiku „bez kratkih pisanja” za blokirajuće sockete i vratit će broj poslanih bajtova na neblokirajućim socketima.

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

Prima podatke sa socketa. Povratna vrijednost je bytes objekt koji predstavlja primljene podatke. Maksimalna količina podataka koja se može primiti odjednom određena je s bufsize.

Opcionalni argument flags je bitovni OR zastavica poruka (MSG_PEEK, MSG_DONTWAIT), koje imaju isto značenje kao u CPythonu.

sendto(bytes: bytes, address: Any) int

Šalje podatke na socket. Socket ne bi trebao biti povezan s udaljenim socketom, budući da je odredišni socket određen s address.

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

Prima podatke sa socketa. Povratna vrijednost je par (bytes, address) gdje je bytes bytes objekt koji predstavlja primljene podatke, a address je adresa socketa koji šalje podatke.

Pogledajte funkciju recv() za objašnjenje opcionalnog argumenta flags.

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

Postavlja vrijednost dane socket opcije. Potrebne simboličke konstante definirane su u modulu socket (SO_* itd.). value može biti cijeli broj ili objekt sličan bajtovima koji predstavlja međuspremnik.

settimeout(value: float | None) None

Postavlja vremensko ograničenje na blokirajuće socket operacije. Argument value može biti nenegativan broj s pomičnim zarezom koji izražava sekunde, ili None. Ako je dana vrijednost različita od nule, naknadne socket operacije izazvat će iznimku OSError ako je razdoblje vremenskog ograničenja proteklo prije nego što je operacija dovršena. Ako je dana nula, socket se stavlja u neblokirajući način rada. Ako je dan None, socket se stavlja u blokirajući način rada.

Prenosiva i generička alternativa je korištenje objekta select.poll. To omogućuje istovremeno čekanje na više objekata (i to ne samo na socketima, već na generičkim stream objektima koji podržavaju prozivanje). Primjer:

# 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

Razlika u odnosu na CPython

CPython izaziva iznimku socket.timeout u slučaju isteka vremena, što je podklasa OSError. MicroPython umjesto toga izaziva OSError izravno. Ako koristite except OSError: za hvatanje iznimke, vaš će kod raditi i u MicroPythonu i u CPythonu.

setblocking(flag: bool) None

Postavlja blokirajući ili neblokirajući način rada socketa: ako je flag false, socket se postavlja na neblokirajući, inače na blokirajući način rada.

Ova je metoda kratica za određene pozive settimeout():

  • sock.setblocking(True) je ekvivalentno sock.settimeout(None)

  • sock.setblocking(False) je ekvivalentno sock.settimeout(0)

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

Vraća datotečni objekt pridružen socketu. Točan vraćeni tip ovisi o argumentima danim metodi makefile(). Podrška je ograničena samo na binarne načine (‘rb’, ‘wb’ i ‘rwb’). CPythonovi argumenti: encoding, errors i newline nisu podržani.

Razlika u odnosu na CPython

Budući da MicroPython ne podržava međuspremane streamove, vrijednost parametra buffering se zanemaruje i tretira kao da je 0 (bez međuspremnika).

Razlika u odnosu na CPython

Zatvaranje datotečnog objekta koji vraća makefile() ZATVORIT ĆE i izvorni socket.

read(size: int | None = None) bytes

Čita do size bajtova sa socketa. Vraća bytes objekt. Ako size nije dan, čita sve podatke dostupne sa socketa do EOF-a; stoga se metoda neće vratiti dok se socket ne zatvori. Ova funkcija pokušava pročitati onoliko podataka koliko je zatraženo (bez „kratkih čitanja”). To, međutim, možda neće biti moguće s neblokirajućim socketom, pa će se tada vratiti manje podataka.

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

Čita bajtove u buf. Ako je naveden nbytes, čita najviše toliko bajtova. Inače čita najviše len(buf) bajtova. Baš kao i read(), ova metoda slijedi politiku „bez kratkih čitanja”.

Povratna vrijednost: broj pročitanih bajtova pohranjenih u buf.

readline() bytes

Čita redak koji završava znakom novog retka.

Povratna vrijednost: pročitani redak.

write(buf: bytes) int

Piše međuspremnik bajtova na socket. Ova će funkcija pokušati zapisati sve podatke na socket (bez „kratkih pisanja”). To, međutim, možda neće biti moguće s neblokirajućim socketom, pa će vraćena vrijednost biti manja od duljine buf.

Povratna vrijednost: broj zapisanih bajtova.

Napomena

MicroPython ne implementira socket.error. CPython ima zastarjelu iznimku socket.error koja je alias za OSError; u MicroPythonu koristite OSError izravno za hvatanje pogrešaka vezanih uz socket.