9.11. Objekti utičnice¶
Python sučelje prema transportnom sloju jest klasa socket.socket. Utičnica predstavlja jednu krajnju točku mrežnog razgovora – adresu, port i protokol (UDP ili TCP) preko kojeg se razgovor odvija. Poglavlja o upravljanju hardverom otvarala su instance UART za komunikaciju po žici; ovaj odjeljak otvara instance socket za komunikaciju po mreži. Oblik je isti; temeljna usluga samo je mnogo sposobnija.
9.11.1. Stvaranje utičnice¶
Tri argumenta opisuju utičnicu: koju adresnu obitelj govori, koji tip utičnice nudi i koji protokol koristi. Zadane vrijednosti pokrivaju slučajeve koje koristi ostatak ovog odjeljka:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # IPv4 TCP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # IPv4 UDP
Dvije konstante između kojih aplikacija bira u gotovo svakom slučaju:
AF_INET– IPv4 adrese (numerički IP plus port). Najčešći izbor.AF_INET6je IPv6 ekvivalent.SOCK_STREAM– TCP veza, pouzdani tok bajtova.SOCK_DGRAMje UDP ekvivalent.
Treći argument (protokol) ostavljen je na nuli, što bira ispravnu zadanu vrijednost na temelju prva dva. Potpuni konstruktor dokumentiran je na socket — modul socket.
9.11.2. Adrese na utičnici¶
Adresa utičnice je n-torka (host, port)
("192.168.1.50", 80)
("0.0.0.0", 8000)
Host je IP adresa kao niz znakova. Port je 16-bitni cijeli broj obrađen na Portovi.
Vrijedi znati nekoliko posebnih nizova hosta:
"0.0.0.0"znači „svako IPv4 sučelje na ovom uređaju”. Poslužitelj vezan na ovu adresu prihvaća veze na bilo kojoj adresi koju kamera drži."127.0.0.1"je localhost – promet prema njoj nikada ne napušta uređaj. Korisno za testiranje."255.255.255.255"je lokalna broadcast adresa. UDP datagram poslan na nju ide svakom uređaju na lokalnom segmentu.
Domenska imena poput "example.com" nisu valjani nizovi hosta u adresi utičnice. Najprije se moraju razriješiti u IP; Imena i DNS pokriva poziv getaddrinfo() koji to čini.
9.11.3. Dvije uloge¶
Životni ciklus utičnice ovisi o tome na kojoj je strani razgovora. Klijentska utičnica poziva connect() (ili, za UDP, samo sendto()) za komunikaciju s poznatim poslužiteljem. Poslužiteljska utičnica poziva bind() da zauzme port, a zatim ili listen() i accept() (za TCP) ili recvfrom() (za UDP) za primanje dolaznog prometa.
Isti konstruktor socket koristi se u oba slučaja; razlikuju se samo metode koje se naknadno pozivaju. Sljedeće tri stranice prolaze kroz praktične obrasce:
UDP utičnice – slanje i primanje datagrama.
TCP utičnice – TCP klijent i poslužitelj.
Utičnice s asyncio – sve navedeno, ali unutar
asynciopetlje događaja.
9.11.4. Zatvaranje utičnice¶
Svaka utičnica drži mali komad stanja operacijskog sustava (rezervaciju porta, međuspremnike, TCP stanje veze). Kad aplikacija završi s njom, close() oslobađa to stanje. Zaboravljena utičnica je spori odljev koji se nagomilava; u petlji koja otvara veze, propušteni close na kraju će iscrpsti kamerin skup dostupnih utičnica.
Najčišći obrazac je naredba with
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(addr)
s.send(b"GET / HTTP/1.0\r\n\r\n")
...
# socket is closed automatically here, even on error
Utičnice implementiraju protokol upravitelja konteksta opisan u Python pregledu, pa blok with jamči da se close() poziva bez obzira na to je li blok izašao normalno ili podizanjem iznimke.
9.11.5. Referenca modula socket¶
Ova i sljedeće stranice prolaze kroz API u pripovjednom obliku. Za potpunu referencu na razini argumenata svake metode, svake zastavice i svake konstante koju modul izlaže, pogledajte socket — modul socket. Referenca je također mjesto za potragu za rjeđim operacijama (opcije utičnice, članstvo u multicast grupi, IPv6 ID-jevi opsega) koje ovaj odjeljak ne pokriva.