Soket digunakan hampir di mana-mana, tetapi merupakan salah satu teknologi yang paling sering disalahpahami. Ini adalah ikhtisar soket 10.000 kaki. Ini sebenarnya bukan tutorial - Anda masih harus bekerja untuk menjalankan semuanya. Itu tidak mencakup poin-poin bagus (dan ada banyak dari mereka), tapi saya harap ini akan memberi Anda latar belakang yang cukup untuk mulai menggunakannya dengan baik. Show SoketSaya hanya akan berbicara tentang INET (mis. e. IPv4), tetapi mereka menyumbang setidaknya 99% dari soket yang digunakan. Dan saya hanya akan berbicara tentang STREAM (mis. e. TCP) soket - kecuali Anda benar-benar tahu apa yang Anda lakukan (dalam hal ini HOWTO ini bukan untuk Anda. ), Anda akan mendapatkan perilaku dan kinerja yang lebih baik dari soket STREAM daripada yang lainnya. Saya akan mencoba untuk menjernihkan misteri tentang apa itu soket, serta beberapa petunjuk tentang cara bekerja dengan soket pemblokiran dan non-pemblokiran. Tapi saya akan mulai dengan berbicara tentang memblokir soket. Anda harus mengetahui cara kerjanya sebelum berurusan dengan soket non-pemblokiran Bagian dari masalah dalam memahami hal-hal ini adalah bahwa "soket" dapat berarti sejumlah hal yang agak berbeda, bergantung pada konteksnya. Jadi pertama-tama, mari kita bedakan antara soket "klien" - titik akhir percakapan, dan soket "server", yang lebih mirip operator switchboard. Aplikasi klien (browser Anda, misalnya) menggunakan soket "klien" secara eksklusif; SejarahDari berbagai bentuk IPC, soket adalah yang paling populer. Pada platform apa pun, kemungkinan ada bentuk IPC lain yang lebih cepat, tetapi untuk komunikasi lintas platform, soket adalah satu-satunya permainan di kota. Mereka ditemukan di Berkeley sebagai bagian dari rasa BSD Unix. Mereka menyebar seperti api dengan internet. Dengan alasan yang bagus - kombinasi soket dengan INET membuat berbicara dengan mesin sewenang-wenang di seluruh dunia menjadi sangat mudah (setidaknya dibandingkan dengan skema lain) Membuat SoketSecara kasar, ketika Anda mengklik tautan yang membawa Anda ke halaman ini, browser Anda melakukan hal seperti berikut # create an INET, STREAMing socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # now connect to the web server on port 80 - the normal http port s.connect(("www.python.org", 80)) Ketika Apa yang terjadi di server web sedikit lebih rumit. Pertama, server web membuat "soket server" # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)_ Beberapa hal yang perlu diperhatikan. kami menggunakan # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)0 menentukan bahwa soket dapat dijangkau oleh alamat apa pun yang dimiliki mesin Hal kedua yang perlu diperhatikan. port nomor rendah biasanya disediakan untuk layanan "terkenal" (HTTP, SNMP dll). Jika Anda bermain-main, gunakan angka tinggi yang bagus (4 digit) Akhirnya, argumen untuk # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)_1 memberi tahu perpustakaan soket bahwa kami ingin mengantri sebanyak 5 permintaan koneksi (maks normal) sebelum menolak koneksi luar. Jika sisa kode ditulis dengan benar, itu pasti banyak Sekarang kita memiliki soket "server", mendengarkan pada port 80, kita dapat memasuki mainloop dari server web while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()_ Sebenarnya ada 3 cara umum di mana loop ini dapat bekerja - mengirim utas untuk menangani # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)2, membuat proses baru untuk menangani # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)2, atau merestrukturisasi aplikasi ini untuk menggunakan soket non-pemblokiran, dan multipleks antara soket "server" kami dan # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)2 aktif . Lebih lanjut tentang itu nanti. Hal penting yang harus dipahami sekarang adalah ini. ini semua yang dilakukan soket "server". Itu tidak mengirim data apa pun. Itu tidak menerima data apa pun. Itu hanya menghasilkan soket "klien". Setiap # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)_2 dibuat sebagai respons terhadap soket "klien" lain yang melakukan # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)7 ke host dan port tempat kita terikat. Segera setelah kami membuat # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)2 itu, kami kembali mendengarkan untuk koneksi lainnya. Kedua "klien" bebas untuk mengobrol - mereka menggunakan beberapa port yang dialokasikan secara dinamis yang akan didaur ulang saat percakapan berakhir IPCJika Anda membutuhkan IPC cepat antara dua proses pada satu mesin, Anda harus melihat ke dalam pipa atau memori bersama. Jika Anda memutuskan untuk menggunakan soket AF_INET, ikat soket "server" ke # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)9. Pada sebagian besar platform, ini akan mengambil jalan pintas di sekitar beberapa lapisan kode jaringan dan menjadi sedikit lebih cepat Lihat juga IPC lintas platform terintegrasi ke dalam API tingkat yang lebih tinggi Menggunakan SoketHal pertama yang perlu diperhatikan, adalah bahwa soket "klien" browser web dan soket "klien" server web adalah binatang buas yang identik. Artinya, ini adalah percakapan "peer to peer". Atau dengan kata lain, sebagai desainer, Anda harus memutuskan apa aturan etiket untuk percakapan. Biasanya, soket Sekarang ada dua set kata kerja yang digunakan untuk komunikasi. Anda dapat menggunakan while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()2 dan while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3, atau Anda dapat mengubah soket klien Anda menjadi binatang seperti file dan menggunakan while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()4 dan while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()5. Yang terakhir adalah cara Java menampilkan soketnya. Saya tidak akan membicarakannya di sini, kecuali untuk memperingatkan Anda bahwa Anda perlu menggunakan while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()6 pada soket. Ini adalah "file" buffer, dan kesalahan umum adalah while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()5 sesuatu, lalu while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()4 untuk balasan. Tanpa while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()6 di sana, Anda mungkin menunggu selamanya untuk balasan, karena permintaan mungkin masih ada di buffer output Anda Sekarang kita sampai pada batu sandungan utama soket - while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()2 dan while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3 beroperasi pada buffer jaringan. Mereka tidak perlu menangani semua byte yang Anda berikan (atau harapkan dari mereka), karena fokus utama mereka adalah menangani buffer jaringan. Secara umum, mereka kembali ketika buffer jaringan terkait telah diisi ( while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()2) atau dikosongkan ( while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3). Mereka kemudian memberi tahu Anda berapa banyak byte yang mereka tangani. Merupakan tanggung jawab Anda untuk menelepon mereka lagi sampai pesan Anda benar-benar ditangani Ketika while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()_3 mengembalikan 0 byte, itu berarti pihak lain telah menutup (atau sedang dalam proses penutupan) koneksi. Anda tidak akan menerima data lagi pada sambungan ini. Pernah. Anda mungkin berhasil mengirim data; Protokol seperti HTTP menggunakan soket hanya untuk satu transfer. Klien mengirim permintaan, lalu membaca balasan. Itu dia. Soket dibuang. Ini berarti klien dapat mendeteksi akhir balasan dengan menerima 0 byte Tetapi jika Anda berencana menggunakan kembali soket Anda untuk transfer lebih lanjut, Anda perlu menyadari bahwa tidak ada EOT pada soket. saya ulangi. jika soket while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()2 atau while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3 kembali setelah menangani 0 byte, koneksi telah terputus. Jika koneksi belum terputus, Anda dapat menunggu di while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3 selamanya, karena soket tidak akan memberi tahu Anda bahwa tidak ada lagi yang perlu dibaca (untuk saat ini). Sekarang jika Anda memikirkannya sedikit, Anda akan menyadari kebenaran mendasar tentang soket. pesan harus memiliki panjang tetap (yuck), atau dibatasi (mengangkat bahu), atau menunjukkan berapa panjangnya (jauh lebih baik), atau diakhiri dengan mematikan koneksi. Pilihan sepenuhnya ada di tangan Anda, (tetapi beberapa cara lebih benar dari yang lain) Dengan asumsi Anda tidak ingin mengakhiri koneksi, solusi paling sederhana adalah pesan dengan panjang tetap class MySocket: """demonstration class only - coded for clarity, not efficiency """ def __init__(self, sock=None): if sock is None: self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM) else: self.sock = sock def connect(self, host, port): self.sock.connect((host, port)) def mysend(self, msg): totalsent = 0 while totalsent < MSGLEN: sent = self.sock.send(msg[totalsent:]) if sent == 0: raise RuntimeError("socket connection broken") totalsent = totalsent + sent def myreceive(self): chunks = [] bytes_recd = 0 while bytes_recd < MSGLEN: chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048)) if chunk == b'': raise RuntimeError("socket connection broken") chunks.append(chunk) bytes_recd = bytes_recd + len(chunk) return b''.join(chunks) Kode pengiriman di sini dapat digunakan untuk hampir semua skema perpesanan - dengan Python Anda mengirim string, dan Anda dapat menggunakan class MySocket: """demonstration class only - coded for clarity, not efficiency """ def __init__(self, sock=None): if sock is None: self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM) else: self.sock = sock def connect(self, host, port): self.sock.connect((host, port)) def mysend(self, msg): totalsent = 0 while totalsent < MSGLEN: sent = self.sock.send(msg[totalsent:]) if sent == 0: raise RuntimeError("socket connection broken") totalsent = totalsent + sent def myreceive(self): chunks = [] bytes_recd = 0 while bytes_recd < MSGLEN: chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048)) if chunk == b'': raise RuntimeError("socket connection broken") chunks.append(chunk) bytes_recd = bytes_recd + len(chunk) return b''.join(chunks)8 untuk menentukan panjangnya (meskipun telah menyematkan class MySocket: """demonstration class only - coded for clarity, not efficiency """ def __init__(self, sock=None): if sock is None: self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM) else: self.sock = sock def connect(self, host, port): self.sock.connect((host, port)) def mysend(self, msg): totalsent = 0 while totalsent < MSGLEN: sent = self.sock.send(msg[totalsent:]) if sent == 0: raise RuntimeError("socket connection broken") totalsent = totalsent + sent def myreceive(self): chunks = [] bytes_recd = 0 while bytes_recd < MSGLEN: chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048)) if chunk == b'': raise RuntimeError("socket connection broken") chunks.append(chunk) bytes_recd = bytes_recd + len(chunk) return b''.join(chunks)9 karakter). Sebagian besar kode penerima yang menjadi lebih kompleks. (Dan di C, itu tidak jauh lebih buruk, kecuali Anda tidak dapat menggunakan ready_to_read, ready_to_write, in_error = \ select.select( potential_readers, potential_writers, potential_errs, timeout)0 jika pesan telah menyematkan class MySocket: """demonstration class only - coded for clarity, not efficiency """ def __init__(self, sock=None): if sock is None: self.sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM) else: self.sock = sock def connect(self, host, port): self.sock.connect((host, port)) def mysend(self, msg): totalsent = 0 while totalsent < MSGLEN: sent = self.sock.send(msg[totalsent:]) if sent == 0: raise RuntimeError("socket connection broken") totalsent = totalsent + sent def myreceive(self): chunks = [] bytes_recd = 0 while bytes_recd < MSGLEN: chunk = self.sock.recv(min(MSGLEN - bytes_recd, 2048)) if chunk == b'': raise RuntimeError("socket connection broken") chunks.append(chunk) bytes_recd = bytes_recd + len(chunk) return b''.join(chunks)9s. ) Penyempurnaan yang paling mudah adalah menjadikan karakter pertama pesan sebagai indikator jenis pesan, dan jenisnya menentukan panjangnya. Sekarang Anda memiliki dua while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3 - yang pertama untuk mendapatkan (setidaknya) karakter pertama sehingga Anda dapat mencari panjangnya, dan yang kedua dalam satu lingkaran untuk mendapatkan sisanya. Jika Anda memutuskan untuk menggunakan rute yang dibatasi, Anda akan menerima beberapa ukuran potongan acak, (4096 atau 8192 sering cocok untuk ukuran buffer jaringan), dan memindai apa yang telah Anda terima untuk pembatas Satu komplikasi yang harus diperhatikan. jika protokol percakapan Anda memungkinkan beberapa pesan untuk dikirim kembali ke belakang (tanpa semacam balasan), dan Anda memberikan while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3 ukuran potongan yang sewenang-wenang, Anda mungkin akan membaca awal dari pesan berikut. Anda harus mengesampingkannya dan mempertahankannya, sampai dibutuhkan Mengawali pesan dengan panjangnya (misalnya, 5 karakter numerik) menjadi lebih rumit, karena (percaya atau tidak), Anda mungkin tidak mendapatkan semua 5 karakter dalam satu while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3. Dalam bermain-main, Anda akan lolos begitu saja; . Menjijikan. Ini juga saat Anda akan menemukan bahwa while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()2 tidak selalu berhasil menyingkirkan semuanya sekaligus. Dan meskipun telah membaca ini, pada akhirnya Anda akan digigit olehnya Demi kepentingan ruang, membangun karakter Anda, (dan mempertahankan posisi kompetitif saya), penyempurnaan ini dibiarkan sebagai latihan bagi pembaca. Mari kita beralih ke pembersihan Data BinerSangat mungkin untuk mengirim data biner melalui soket. Masalah utamanya adalah tidak semua mesin menggunakan format yang sama untuk data biner. Misalnya, adalah big-endian, dengan byte paling signifikan terlebih dahulu, jadi integer 16 bit dengan nilai ready_to_read, ready_to_write, in_error = \ select.select( potential_readers, potential_writers, potential_errs, timeout)7 akan menjadi dua byte hex ready_to_read, ready_to_write, in_error = \ select.select( potential_readers, potential_writers, potential_errs, timeout)8. Namun, sebagian besar prosesor umum (x86/AMD64, ARM, RISC-V), adalah little-endian, dengan byte paling signifikan terlebih dahulu - ready_to_read, ready_to_write, in_error = \ select.select( potential_readers, potential_writers, potential_errs, timeout)7 yang sama akan menjadi connect 0Pustaka soket memiliki panggilan untuk mengonversi bilangan bulat 16 dan 32 bit - Pada hari-hari mesin 64-bit ini, representasi data biner ASCII seringkali lebih kecil daripada representasi biner. Itu karena jumlah waktu yang mengejutkan, sebagian besar bilangan bulat memiliki nilai 0, atau mungkin 1. String MemutuskanSebenarnya, Anda seharusnya menggunakan Salah satu cara untuk menggunakan while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()_2 selesai dengan sukses maka, memang, klien masih menerima Python mengambil shutdown otomatis selangkah lebih maju, dan mengatakan bahwa ketika soket dikumpulkan sampah, itu akan secara otomatis melakukan Ketika Soket MatiMungkin hal terburuk tentang menggunakan soket pemblokiran adalah apa yang terjadi ketika pihak lain turun dengan keras (tanpa melakukan Soket Tanpa PemblokiranJika Anda sudah memahami sebelumnya, Anda sudah tahu sebagian besar dari apa yang perlu Anda ketahui tentang mekanisme penggunaan soket. Anda masih akan menggunakan panggilan yang sama, dengan cara yang hampir sama. Hanya saja, jika Anda melakukannya dengan benar, aplikasi Anda akan hampir habis-habisan Di Python, Anda menggunakan Perbedaan mekanis utama adalah bahwa while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()2, while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3, connect dan socket.gethostname() 3 dapat kembali tanpa melakukan apa pun. Anda memiliki (tentu saja) sejumlah pilihan. Anda dapat memeriksa kode pengembalian dan kode kesalahan dan umumnya membuat diri Anda gila. Jika Anda tidak mempercayai saya, cobalah kapan-kapan. Aplikasi Anda akan tumbuh besar, bermasalah, dan menyedot CPU. Jadi mari kita lewati solusi mati otak dan lakukan dengan benarGunakan # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)_5 Di C, pengkodean # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)_5 cukup rumit. Di Python, ini sangat mudah, tetapi cukup mirip dengan versi C sehingga jika Anda memahami # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)5 dengan Python, Anda akan mengalami sedikit masalah dengannya di C ready_to_read, ready_to_write, in_error = \ select.select( potential_readers, potential_writers, potential_errs, timeout) Anda melewati # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)_5 tiga daftar. yang pertama berisi semua soket yang mungkin ingin Anda coba baca; . Anda harus mencatat bahwa soket dapat masuk ke lebih dari satu daftar. Panggilan # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)5 memblokir, tetapi Anda dapat memberikan waktu tunggu. Ini umumnya adalah hal yang masuk akal untuk dilakukan - berikan waktu tunggu yang lama (katakanlah sebentar) kecuali Anda memiliki alasan yang kuat untuk melakukan sebaliknya Sebagai imbalannya, Anda akan mendapatkan tiga daftar. Mereka berisi soket yang sebenarnya dapat dibaca, dapat ditulis, dan dalam kesalahan. Masing-masing daftar ini adalah subset (kemungkinan kosong) dari daftar terkait yang Anda berikan Jika soket ada dalam daftar keluaran yang dapat dibaca, Anda dapat sedekat mungkin dengan yang pernah kami dapatkan dalam bisnis ini bahwa while True: # accept connections from outside (clientsocket, address) = serversocket.accept() # now do something with the clientsocket # in this case, we'll pretend this is a threaded server ct = client_thread(clientsocket) ct.run()3 pada soket itu akan mengembalikan sesuatu. Ide yang sama untuk daftar yang dapat ditulis. Anda akan dapat mengirim sesuatu. Mungkin tidak semua yang Anda inginkan, tetapi ada sesuatu yang lebih baik daripada tidak sama sekali. (Sebenarnya, setiap soket yang cukup sehat akan kembali sebagai dapat ditulisi - itu hanya berarti tersedia ruang buffer jaringan keluar. ) Jika Anda memiliki soket "server", masukkan ke dalam daftar potential_readers. Jika muncul dalam daftar yang dapat dibaca, Sebenarnya, # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)_5 dapat berguna bahkan dengan soket pemblokiran. Ini adalah salah satu cara untuk menentukan apakah Anda akan memblokir - soket kembali dapat dibaca ketika ada sesuatu di buffer. Namun, ini masih tidak membantu dengan masalah menentukan apakah ujung yang lain sudah selesai, atau hanya sibuk dengan hal lain Peringatan portabilitas. Di Unix, # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)5 berfungsi baik dengan soket maupun file. Jangan coba ini di Windows. Di Windows, # create an INET, STREAMing socket serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind the socket to a public host, and a well-known port serversocket.bind((socket.gethostname(), 80)) # become a server socket serversocket.listen(5)_5 hanya berfungsi dengan soket. Perhatikan juga bahwa di C, banyak opsi soket yang lebih canggih dilakukan secara berbeda di Windows. Faktanya, di Windows saya biasanya menggunakan utas (yang bekerja sangat, sangat baik) dengan soket saya Bagaimana cara saya terhubung ke server dengan python?Server Sederhana
. Selanjutnya, panggil metode accept dari objek yang dikembalikan. Metode ini menunggu hingga klien terhubung ke port yang Anda tentukan, lalu mengembalikan objek koneksi yang mewakili koneksi ke klien tersebut. call bind(hostname, port) function to specify a port for your service on the given host. Next, call the accept method of the returned object. This method waits until a client connects to the port you specified, and then returns a connection object that represents the connection to that client.
Bagaimana cara menghubungkan server ke klien dengan python?Langkah pertama adalah mengimpor modul soket dan kemudian membuat soket seperti yang Anda lakukan saat membuat server. Kemudian, untuk membuat koneksi antara server-klien, Anda perlu menggunakan metode connect() dengan menentukan (host, port) .
Bagaimana cara saya mendengarkan server python?Server memiliki metode bind() yang mengikatnya ke IP dan port tertentu sehingga dapat mendengarkan permintaan masuk pada IP dan port tersebut. Server memiliki metode listen() yang menempatkan server ke mode mendengarkan . Hal ini memungkinkan server untuk mendengarkan koneksi masuk. Dan terakhir server memiliki metode accept() dan close().
Apa yang dilakukan connect () dengan python?Itu. fungsi connect() adalah menghubungkan soket TCP ke server jarak jauh, yang memungkinkan data dikirim ke dan diterima dari server . Dalam kasus Anda, Anda menggunakan soket TCP untuk mengirim perintah HTTP, dan menerima respons HTTP yang sesuai. |