9.11. Socket-objekt

Python-gränssnittet mot transportlagret är klassen socket.socket. En socket representerar en ändpunkt i en nätverkskonversation – en adress, en port och det protokoll (UDP eller TCP) som konversationen körs över. Kapitlen om hårdvarustyrning öppnade UART-instanser för att kommunicera på en ledning; det här avsnittet öppnar socket-instanser för att kommunicera på nätverket. Formen är densamma; den underliggande tjänsten är bara mycket mer kapabel.

9.11.1. Skapa en socket

Tre argument beskriver en socket: vilken adressfamilj den talar, vilken socket-typ den erbjuder och vilket protokoll den använder. Standardvärdena täcker de fall som resten av detta avsnitt använder:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   # IPv4 TCP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)    # IPv4 UDP

De två konstanter som applikationen väljer mellan i nästan alla fall:

  • AF_INET – IPv4-adresser (en numerisk IP plus en port). Det vanligaste valet. AF_INET6 är IPv6-motsvarigheten.

  • SOCK_STREAM – en TCP-anslutning, den tillförlitliga byteströmmen. SOCK_DGRAM är UDP-motsvarigheten.

Det tredje argumentet (protokollet) lämnas på noll, vilket väljer rätt standardvärde baserat på de två första. Den fullständiga konstruktorn är dokumenterad på socket — socket-modul.

9.11.2. Adresser på en socket

En socket-adress är en tupel av (host, port)

("192.168.1.50", 80)
("0.0.0.0", 8000)

Värddatorn är IP-adressen som en sträng. Porten är det 16-bitars heltal som beskrivs på Portar.

En handfull speciella värdsträngar är värda att känna till:

  • "0.0.0.0" betyder ”varje IPv4-gränssnitt på den här enheten”. En server bunden till denna adress accepterar anslutningar på vilken adress kameran än har.

  • "127.0.0.1" är localhost – trafik till den lämnar aldrig enheten. Användbart för testning.

  • "255.255.255.255" är den lokala broadcast-adressen. Ett UDP-datagram som skickas till den går till varje enhet på det lokala segmentet.

Domännamn som "example.com" är inte giltiga värdsträngar i en socket-adress. De måste först översättas till en IP; Namn och DNS täcker anropet getaddrinfo() som gör det.

9.11.3. De två rollerna

En sockets livscykel beror på vilken sida av konversationen den befinner sig på. En klient-socket anropar connect() (eller, för UDP, bara sendto()) för att kommunicera med en känd server. En server-socket anropar bind() för att göra anspråk på en port, och därefter antingen listen() och accept() (för TCP) eller recvfrom() (för UDP) för att ta emot inkommande trafik.

Samma socket-konstruktor används i båda fallen; det är bara metoderna som anropas efteråt som skiljer sig. De tre nästa sidorna går igenom de praktiska mönstren:

9.11.4. Stänga en socket

Varje socket håller en liten bit operativsystemstillstånd (en portreservation, buffertar, anslutningens TCP-tillstånd). När applikationen är klar med den frigör close() det tillståndet. En bortglömd socket är en långsam läcka som ackumuleras; i en loop som öppnar anslutningar kommer en utebliven close så småningom att tömma kamerans pool av tillgängliga sockets.

Det renaste mönstret är with-satsen:

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

Sockets implementerar protokollet för kontexthanterare som beskrivs i Python-översikten, så with-blocket garanterar att close() anropas oavsett om blocket avslutades normalt eller genom att kasta ett undantag.

9.11.5. Referensen för socket

Den här och de nästa sidorna går igenom API:t i berättande form. För den fullständiga argumentnivåreferensen över varje metod, varje flagga och varje konstant som modulen exponerar, se socket — socket-modul. Referensen är också platsen att leta efter de mindre vanliga operationerna (socket-alternativ, medlemskap i multicast-grupper, IPv6-scope-ID:n) som det här avsnittet inte täcker.