socket --- modul socket

Modul ini menyediakan akses ke antarmuka socket BSD.

Perbedaan dengan CPython

Demi efisiensi dan konsistensi, objek socket di MicroPython mengimplementasikan antarmuka stream (mirip file) secara langsung. Di CPython, Anda perlu mengonversi socket ke objek mirip file menggunakan metode makefile(). Metode ini masih didukung oleh MicroPython (tetapi merupakan no-op), sehingga jika kompatibilitas dengan CPython penting, pastikan untuk menggunakannya.

Format alamat socket

Format alamat socket asli dari modul socket adalah tipe data buram yang dikembalikan oleh fungsi getaddrinfo(), yang harus digunakan untuk menyelesaikan alamat tekstual (termasuk alamat numerik):

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)

Menggunakan getaddrinfo() adalah cara paling efisien (baik dalam hal memori maupun daya pemrosesan) dan portabel untuk bekerja dengan alamat.

Modul socket juga menyediakan cara yang kompatibel dengan CPython untuk menentukan alamat menggunakan tuple, seperti dijelaskan di bawah. Pada OpenMV Cam, modul socket sudah bawaan; alamat numerik dapat diberikan langsung dalam format tuple, tetapi nama domain harus diselesaikan terlebih dahulu dengan getaddrinfo().

Ringkasan:

  • Selalu gunakan getaddrinfo() untuk menyelesaikan nama host.

  • Alamat tuple yang dijelaskan di bawah dapat digunakan sebagai pintasan untuk alamat numerik, untuk keperluan cepat dan penggunaan interaktif.

Format alamat tuple untuk modul socket:

  • IPv4: (ipv4_address, port), di mana ipv4_address adalah string dengan alamat IPv4 numerik notasi titik, mis. "8.8.8.8", dan port adalah nomor port integer dalam rentang 1-65535. Nama domain tidak diterima sebagai ipv4_address; selesaikan terlebih dahulu menggunakan getaddrinfo().

  • IPv6: (ipv6_address, port, flowinfo, scopeid), di mana ipv6_address adalah string dengan alamat IPv6 numerik notasi titik dua, mis. "2001:db8::1", dan port adalah nomor port integer dalam rentang 1-65535. flowinfo harus 0. scopeid adalah pengidentifikasi cakupan antarmuka untuk alamat link-local. Nama domain tidak diterima sebagai ipv6_address; selesaikan terlebih dahulu menggunakan getaddrinfo().

Fungsi

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

Terjemahkan argumen host/port menjadi urutan 5-tuple yang berisi semua argumen yang diperlukan untuk membuat socket yang terhubung ke layanan tersebut. Argumen af, type, dan proto (yang memiliki arti yang sama seperti untuk fungsi socket) dapat digunakan untuk memfilter jenis alamat yang dikembalikan. Jika parameter tidak ditentukan atau nol, semua kombinasi alamat dapat dikembalikan (memerlukan pemfilteran di sisi pengguna).

Daftar 5-tuple yang dihasilkan memiliki struktur berikut:

(family, type, proto, canonname, sockaddr)

Contoh berikut menunjukkan cara menghubungkan ke url tertentu:

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

Penggunaan yang disarankan untuk parameter pemfilteran:

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

Perbedaan dengan CPython

CPython memunculkan pengecualian socket.gaierror (subkelas OSError) dalam kasus kesalahan pada fungsi ini. MicroPython tidak memiliki socket.gaierror dan memunculkan OSError secara langsung. Perhatikan bahwa nomor kesalahan dari getaddrinfo() membentuk namespace terpisah dan mungkin tidak cocok dengan nomor kesalahan dari modul errno. Untuk membedakan kesalahan getaddrinfo(), kesalahan tersebut direpresentasikan dengan angka negatif, sedangkan kesalahan sistem standar adalah angka positif (nomor kesalahan dapat diakses menggunakan properti e.args[0] dari objek pengecualian). Penggunaan nilai negatif adalah detail sementara yang dapat berubah di masa mendatang.

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

Konversi alamat jaringan biner bin_addr dari keluarga alamat af yang diberikan ke representasi tekstual:

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

Konversi alamat jaringan tekstual txt_addr dari keluarga alamat af yang diberikan ke representasi biner:

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

Konstanta

socket.AF_INET: int

Keluarga alamat IPv4.

socket.AF_INET6: int

Keluarga alamat IPv6.

socket.SOCK_STREAM: int

Tipe socket stream (TCP).

socket.SOCK_DGRAM: int

Tipe socket datagram (UDP).

socket.SOCK_RAW: int

Tipe socket mentah.

socket.IPPROTO_IP: int

Tingkat protokol IP. Digunakan sebagai argumen level untuk setsockopt() bersama dengan opsi IP_*.

socket.IPPROTO_TCP: int

Protokol TCP. Anda tidak perlu meneruskan ini ke socket (tipe socket SOCK_STREAM memilihnya secara otomatis); satu-satunya kegunaan nyatanya adalah sebagai argumen level untuk setsockopt() bersama dengan opsi TCP_*.

socket.SOL_SOCKET: int

Tingkat opsi socket. Digunakan sebagai argumen level untuk setsockopt() bersama dengan opsi SO_*.

socket.SO_REUSEADDR: int

Izinkan socket mengikat ke alamat/port yang masih dalam status TIME_WAIT.

socket.SO_BROADCAST: int

Izinkan pengiriman datagram ke alamat broadcast.

socket.SO_KEEPALIVE: int

Aktifkan transmisi berkala probe keep-alive pada socket yang terhubung.

socket.SO_SNDTIMEO: int

Timeout pengiriman, dalam milidetik, diteruskan sebagai argumen value ke setsockopt().

socket.SO_RCVTIMEO: int

Timeout penerimaan, dalam milidetik, diteruskan sebagai argumen value ke setsockopt().

socket.IP_ADD_MEMBERSHIP: int

Bergabung ke grup multicast. Opsi setsockopt() tingkat IPPROTO_IP.

socket.IP_DROP_MEMBERSHIP: int

Keluar dari grup multicast. Opsi setsockopt() tingkat IPPROTO_IP.

socket.TCP_NODELAY: int

Nonaktifkan algoritma Nagle. Opsi setsockopt() tingkat IPPROTO_TCP.

socket.MSG_PEEK: int

Untuk recv() / recvfrom(): kembalikan data tanpa menghapusnya dari antrian input.

socket.MSG_DONTWAIT: int

Untuk recv() / recvfrom(): lakukan operasi dalam mode non-blocking.

Kelas

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

Buat socket baru menggunakan keluarga alamat, tipe socket, dan nomor protokol yang diberikan. Menentukan proto dalam kebanyakan kasus tidak diperlukan (dan tidak disarankan); argumen type memilih protokol yang diperlukan secara otomatis:

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

Tandai socket sebagai ditutup dan lepaskan semua sumber daya. Setelah itu terjadi, semua operasi mendatang pada objek socket akan gagal. Ujung jarak jauh akan menerima indikasi EOF jika didukung oleh protokol.

Socket ditutup secara otomatis ketika di-garbage-collect, tetapi disarankan untuk memanggil close() secara eksplisit segera setelah selesai bekerja dengannya.

bind(address: Any) None

Ikat socket ke address. Socket belum boleh terikat.

listen(backlog: int = 2) None

Aktifkan server untuk menerima koneksi. Jika backlog ditentukan, nilainya harus minimal 0 (jika lebih rendah, akan diatur ke 0); dan menentukan jumlah koneksi yang belum diterima yang akan diizinkan sistem sebelum menolak koneksi baru. Jika tidak ditentukan, nilai default yang wajar dipilih.

accept() Tuple['socket', Tuple]

Terima koneksi. Socket harus terikat ke alamat dan mendengarkan koneksi. Nilai kembalian adalah pasangan (conn, address) di mana conn adalah objek socket baru yang dapat digunakan untuk mengirim dan menerima data pada koneksi, dan address adalah alamat yang terikat ke socket di ujung koneksi lainnya.

connect(address: Any) None

Hubungkan ke socket jarak jauh di address.

send(bytes: bytes) int

Kirim data ke socket. Socket harus terhubung ke socket jarak jauh. Mengembalikan jumlah byte yang dikirim, yang mungkin lebih kecil dari panjang data ("short write").

sendall(bytes: bytes) None

Kirim semua data ke socket. Socket harus terhubung ke socket jarak jauh. Tidak seperti send(), metode ini akan mencoba mengirim semua data, dengan mengirim data sepotong demi sepotong secara berurutan.

Perilaku metode ini pada socket non-blocking tidak terdefinisi. Karena itu, di MicroPython, disarankan untuk menggunakan metode write() sebagai gantinya, yang memiliki kebijakan "no short writes" yang sama untuk socket blocking, dan akan mengembalikan jumlah byte yang dikirim pada socket non-blocking.

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

Terima data dari socket. Nilai kembalian adalah objek bytes yang merepresentasikan data yang diterima. Jumlah maksimum data yang diterima sekaligus ditentukan oleh bufsize.

Argumen flags opsional adalah OR bitwise dari flag pesan (MSG_PEEK, MSG_DONTWAIT), yang memiliki arti yang sama seperti di CPython.

sendto(bytes: bytes, address: Any) int

Kirim data ke socket. Socket tidak boleh terhubung ke socket jarak jauh, karena socket tujuan ditentukan oleh address.

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

Terima data dari socket. Nilai kembalian adalah pasangan (bytes, address) di mana bytes adalah objek bytes yang merepresentasikan data yang diterima dan address adalah alamat socket pengirim data.

Lihat fungsi recv() untuk penjelasan argumen flags opsional.

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

Atur nilai opsi socket yang diberikan. Konstanta simbolik yang diperlukan didefinisikan dalam modul socket (SO_* dll.). value dapat berupa integer atau objek mirip bytes yang merepresentasikan buffer.

settimeout(value: float | None) None

Atur timeout pada operasi socket blocking. Argumen value dapat berupa angka floating point non-negatif yang menyatakan detik, atau None. Jika nilai non-nol diberikan, operasi socket berikutnya akan memunculkan pengecualian OSError jika periode timeout telah berlalu sebelum operasi selesai. Jika nol diberikan, socket diatur ke mode non-blocking. Jika None diberikan, socket diatur ke mode blocking.

Alternatif yang portabel dan generik adalah menggunakan objek select.poll. Ini memungkinkan menunggu beberapa objek sekaligus (bukan hanya socket, tetapi objek stream generik yang mendukung polling). Contoh:

# 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

Perbedaan dengan CPython

CPython memunculkan pengecualian socket.timeout dalam kasus timeout, yang merupakan subkelas OSError. MicroPython memunculkan OSError secara langsung. Jika Anda menggunakan except OSError: untuk menangkap pengecualian, kode Anda akan berfungsi baik di MicroPython maupun CPython.

setblocking(flag: bool) None

Atur mode blocking atau non-blocking pada socket: jika flag bernilai false, socket diatur ke non-blocking, jika tidak ke mode blocking.

Metode ini adalah singkatan untuk beberapa panggilan settimeout() tertentu:

  • sock.setblocking(True) setara dengan sock.settimeout(None)

  • sock.setblocking(False) setara dengan sock.settimeout(0)

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

Kembalikan objek file yang terkait dengan socket. Tipe kembalian yang tepat bergantung pada argumen yang diberikan ke makefile(). Dukungan terbatas hanya pada mode biner ('rb', 'wb', dan 'rwb'). Argumen CPython: encoding, errors dan newline tidak didukung.

Perbedaan dengan CPython

Karena MicroPython tidak mendukung stream yang di-buffer, nilai parameter buffering diabaikan dan diperlakukan seolah bernilai 0 (tidak di-buffer).

Perbedaan dengan CPython

Menutup objek file yang dikembalikan oleh makefile() AKAN menutup socket asli juga.

read(size: int | None = None) bytes

Baca hingga size byte dari socket. Kembalikan objek bytes. Jika size tidak diberikan, semua data yang tersedia dibaca dari socket hingga EOF; karena itu metode tidak akan kembali sampai socket ditutup. Fungsi ini mencoba membaca sebanyak data yang diminta (tanpa "short reads"). Hal ini mungkin tidak dapat dilakukan dengan socket non-blocking, dan dalam kasus itu data yang lebih sedikit akan dikembalikan.

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

Baca byte ke dalam buf. Jika nbytes ditentukan, baca paling banyak sejumlah byte tersebut. Jika tidak, baca paling banyak len(buf) byte. Seperti read(), metode ini mengikuti kebijakan "no short reads".

Nilai kembalian: jumlah byte yang dibaca dan disimpan ke dalam buf.

readline() bytes

Baca satu baris, diakhiri dengan karakter newline.

Nilai kembalian: baris yang dibaca.

write(buf: bytes) int

Tulis buffer byte ke socket. Fungsi ini akan mencoba menulis semua data ke socket (tanpa "short writes"). Hal ini mungkin tidak dapat dilakukan dengan socket non-blocking, dan nilai yang dikembalikan akan kurang dari panjang buf.

Nilai kembalian: jumlah byte yang ditulis.

Catatan

MicroPython tidak mengimplementasikan socket.error. CPython memiliki pengecualian socket.error yang sudah usang dan merupakan alias dari OSError; di MicroPython, gunakan OSError secara langsung untuk menangkap kesalahan yang berkaitan dengan socket.