9.11. Objek socket¶
Antarmuka Python ke lapisan transport adalah kelas socket.socket. Sebuah socket mewakili satu titik akhir dari sebuah percakapan jaringan -- sebuah alamat, port, dan protokol (UDP atau TCP) yang digunakan percakapan tersebut. Bab-bab kontrol hardware membuka instans UART untuk berkomunikasi melalui kabel; bagian ini membuka instans socket untuk berkomunikasi melalui jaringan. Bentuknya sama; layanan yang mendasarinya jauh lebih mampu.
9.11.1. Membuat socket¶
Tiga argumen mendeskripsikan sebuah socket: address family yang digunakan, socket type yang ditawarkan, dan protocol yang digunakan. Default mencakup kasus yang digunakan sisa bagian ini:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # IPv4 TCP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # IPv4 UDP
Dua konstanta yang dipilih aplikasi dalam hampir setiap kasus:
AF_INET-- alamat IPv4 (IP numerik ditambah port). Pilihan yang paling umum.AF_INET6adalah padanan IPv6.SOCK_STREAM-- koneksi TCP, aliran byte yang andal.SOCK_DGRAMadalah padanan UDP.
Argumen ketiga (protocol) dibiarkan nol, yang memilih default yang tepat berdasarkan dua argumen pertama. Konstruktor lengkap didokumentasikan di socket --- modul socket.
9.11.2. Alamat pada socket¶
Alamat socket adalah tuple (host, port)
("192.168.1.50", 80)
("0.0.0.0", 8000)
Host adalah alamat IP sebagai string. Port adalah bilangan bulat 16-bit yang dibahas di Port.
Beberapa string host khusus yang perlu diketahui:
"0.0.0.0"berarti "setiap antarmuka IPv4 pada perangkat ini". Server yang terikat ke alamat ini menerima koneksi pada alamat mana pun yang dimiliki kamera."127.0.0.1"adalah localhost -- lalu lintas ke sana tidak pernah meninggalkan perangkat. Berguna untuk pengujian."255.255.255.255"adalah alamat broadcast lokal. Datagram UDP yang dikirim ke sana akan pergi ke setiap perangkat di segmen lokal.
Nama domain seperti "example.com" tidak valid sebagai string host dalam alamat socket. Nama domain harus terlebih dahulu diselesaikan menjadi IP; Nama dan DNS mencakup panggilan getaddrinfo() yang melakukan hal tersebut.
9.11.3. Dua peran¶
Siklus hidup socket bergantung pada sisi percakapan mana ia berada. Socket klien memanggil connect() (atau, untuk UDP, cukup sendto()) untuk berbicara ke server yang dikenal. Socket server memanggil bind() untuk mengklaim port, kemudian listen() dan accept() (untuk TCP) atau recvfrom() (untuk UDP) untuk menerima lalu lintas masuk.
Konstruktor socket yang sama digunakan di kedua kasus; hanya metode yang dipanggil setelahnya yang berbeda. Tiga halaman berikutnya memandu melalui pola praktisnya:
UDP sockets -- kirim dan terima datagram.
TCP sockets -- klien dan server TCP.
Socket dengan asyncio -- semua hal di atas, tetapi di dalam event loop
asyncio.
9.11.4. Menutup socket¶
Setiap socket menyimpan sedikit kondisi sistem operasi (reservasi port, buffer, kondisi TCP koneksi). Ketika aplikasi selesai menggunakannya, close() melepaskan kondisi tersebut. Socket yang terlupakan adalah kebocoran lambat yang terakumulasi; dalam loop yang membuka koneksi, melewatkan close pada akhirnya akan menghabiskan pool socket yang tersedia di kamera.
Pola yang paling bersih adalah pernyataan 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
Socket mengimplementasikan protokol context-manager yang dibahas dalam ikhtisar Python, sehingga blok with menjamin close() dipanggil terlepas dari apakah blok tersebut keluar secara normal atau dengan memunculkan pengecualian.
9.11.5. Referensi socket¶
Halaman ini dan halaman berikutnya memandu melalui API dalam bentuk naratif. Untuk referensi tingkat argumen lengkap dari setiap metode, setiap flag, dan setiap konstanta yang diekspos modul, lihat socket --- modul socket. Referensi juga merupakan tempat untuk mencari operasi yang kurang umum (opsi socket, keanggotaan grup multicast, ID scope IPv6) yang tidak dicakup bagian ini.