Bagaimana cara kerja socket API accept ()?

126

API soket adalah standar de-facto untuk komunikasi TCP / IP dan UDP / IP (yaitu, kode jaringan seperti yang kita kenal). Namun, salah satu fungsi intinya, accept()agak ajaib.

Meminjam definisi semi formal:

accept () digunakan di sisi server. Ia menerima upaya masuk yang diterima untuk membuat sambungan TCP baru dari klien jarak jauh, dan membuat soket baru yang terkait dengan pasangan alamat soket sambungan ini.

Dengan kata lain, acceptmengembalikan soket baru di mana server dapat berkomunikasi dengan klien yang baru terhubung. Soket lama (yang acceptdisebut) tetap terbuka, di port yang sama, mendengarkan koneksi baru.

Bagaimana accept kerjanya? Bagaimana penerapannya? Ada banyak kebingungan tentang topik ini. Banyak orang mengklaim menerima membuka port baru dan Anda berkomunikasi dengan klien melalui itu. Tetapi ini jelas tidak benar, karena tidak ada port baru yang dibuka. Anda sebenarnya dapat berkomunikasi melalui port yang sama dengan klien yang berbeda, tetapi bagaimana caranya? Ketika beberapa utas memanggil recvpada port yang sama, bagaimana data tahu ke mana harus pergi?

Saya kira itu adalah sesuatu di sepanjang baris alamat klien yang dikaitkan dengan deskriptor soket, dan setiap kali data masuk, recvitu dialihkan ke soket yang benar, tetapi saya tidak yakin.

Akan sangat bagus untuk mendapatkan penjelasan menyeluruh tentang cara kerja mekanisme ini.

Eli Bendersky
sumber
2
jadi untuk setiap permintaan klien, koneksi soket baru di ujung server dibuka. Server harus selalu terbuka pada jam 80 untuk mendengarkan panggilan masuk. Jika menerima panggilan, maka segera membuat soket BARU dengan empat tupel seperti yang disebutkan di bawah ini, yang akan membuat koneksi TCP antara klien dan server. Apakah pemahaman saya benar?
badai otak
1
Ini adalah pertanyaan yang sangat mendasar dan saya baru-baru ini mengujinya dalam sebuah wawancara: stackoverflow.com/questions/24871827/… Jika Anda memiliki komentar tentang ini, silakan posting
brain storm
@brainstorm Hanya jika Anda sepenuhnya mengabaikan keberadaan HTTP tetap-hidup.
Marquis dari Lorne

Jawaban:

140

Kebingungan Anda terletak pada pemikiran bahwa soket diidentifikasi oleh Server IP: Server Port. Pada kenyataannya, soket secara unik diidentifikasi oleh kuartet informasi:

Client IP : Client Port dan Server IP : Server Port

Jadi, sementara IP Server dan Port Server konstan di semua koneksi yang diterima, informasi sisi klienlah yang memungkinkannya melacak ke mana arah semuanya.

Contoh untuk memperjelas hal:

Katakanlah kita memiliki server di 192.168.1.1:80dan dua klien, 10.0.0.1dan 10.0.0.2.

10.0.0.1membuka koneksi di port lokal 1234dan terhubung ke server. Sekarang server memiliki satu soket yang diidentifikasi sebagai berikut:

10.0.0.1:1234 - 192.168.1.1:80  

Sekarang 10.0.0.2membuka koneksi di port lokal 5678dan terhubung ke server. Sekarang server memiliki dua soket yang diidentifikasi sebagai berikut:

10.0.0.1:1234 - 192.168.1.1:80  
10.0.0.2:5678 - 192.168.1.1:80
17 dari 26
sumber
3
Saya tidak tahu detail implementasi (yang mungkin berbeda dari platform ke platform), saya hanya tahu bahwa secara konseptual soket diidentifikasi oleh kuartet informasi yang saya jelaskan.
17 dari 26
3
Apakah Anda punya referensi tentang ini?
qeek
3
Pertanyaan acak: Apa yang terjadi jika NAT sedang digunakan, dan dua klien di jaringan yang sama mencoba menggunakan porta lokal yang sama saat menyambung ke server? Misalnya, jika 10.0.0.1 dan 10.0.0.2 keduanya terhubung ke router dengan IP eksternal 192.168.0.1, maka server di 192.168.1.1 melihat dua koneksi dari 192.168.0.1. Apa yang terjadi dalam kasus itu jika kebetulan generator nomor acak 10.0.0.1 dan 10.0.0.2 memilih porta lokal yang sama?
Apakah
4
Dukungan NAT di router menangani detail di sana. Lalu lintas jaringan sebenarnya melewati dua koneksi - klien ke router, dan router ke server. Router membuat koneksi keluar pada dua port berbeda 192.168.0.1:1234 dan 192.168.0.1:5678. Lalu lintas masuk kemudian dialihkan oleh router ke klien yang benar.
17 dari 26
3
Jika soket dikenali oleh kuartet, apa informasi kuartet dari soket pendengar?
Eric Zheng
74

Hanya untuk menambah jawaban yang diberikan oleh pengguna "17 dari 26"

Soket sebenarnya terdiri dari 5 tuple - (ip sumber, port sumber, ip tujuan, port tujuan, protokol). Di sini protokol bisa TCP atau UDP atau protokol lapisan transport. Protokol ini diidentifikasi dalam paket dari bidang 'protokol' di datagram IP.

Dengan demikian dimungkinkan untuk memiliki aplikasi yang berbeda di server yang berkomunikasi ke klien yang sama pada 4-tupel yang persis sama tetapi berbeda dalam bidang protokol. Sebagai contoh

Apache di sisi server berbicara di (server1.com:880-client1:1234 di TCP) dan World of Warcraft berbicara di (server1.com:880-client1:1234 di UDP)

Baik klien dan server akan menangani ini karena bidang protokol dalam paket IP dalam kedua kasus berbeda meskipun keempat bidang lainnya sama.

Methos
sumber
13

Yang membuat saya bingung ketika saya mempelajari ini, adalah istilah socketdan portmenyarankan bahwa mereka adalah sesuatu yang fisik, padahal sebenarnya itu hanya struktur data yang digunakan kernel untuk mengabstraksi detail jaringan.

Dengan demikian, struktur data diimplementasikan untuk dapat memisahkan koneksi dari klien yang berbeda. Mengenai bagaimana mereka diimplementasikan, jawabannya adalah a.) Tidak masalah, tujuan dari sockets API adalah agar penerapannya tidak penting atau b.) Hanya untuk melihat-lihat. Terlepas dari buku Stevens yang sangat direkomendasikan yang memberikan penjelasan rinci tentang satu implementasi, lihat sumbernya di Linux atau Solaris atau di salah satu BSD.

a2800276
sumber
Ya, sebagian besar terminologi jaringan hanya menetapkan nama ke kumpulan bit tertentu dan keputusan yang diambil berdasarkan nilainya ("pengidentifikasi protokol", "perutean", "pengikatan", "soket", dll.). Semua perangkat keras kartu jaringan Anda dirancang untuk menerima aliran bit. Apa yang terjadi pada mereka sehubungan dengan program di komputer Anda ditentukan oleh driver dan OS. Kita bisa menyingkirkan semua terminologi itu besok jika kita mau, tetapi prinsip pengiriman aliran bit tampaknya mendasar ...
masterxilo
-1

Seperti yang dikatakan orang lain, soket secara unik diidentifikasi oleh 4-tuple (IP Klien, Port Klien, IP Server, Port Server).

Proses server yang berjalan pada IP Server memelihara database (artinya saya tidak peduli jenis tabel / daftar / pohon / larik / struktur data ajaib yang digunakannya) dari soket aktif dan mendengarkan di Port Server. Ketika menerima pesan (melalui tumpukan TCP / IP server), ia memeriksa IP dan Port Klien terhadap database. Jika IP Klien dan Port Klien ditemukan dalam entri database, pesan akan diteruskan ke penangan yang ada, jika tidak entri database baru dibuat dan penangan baru muncul untuk menangani soket itu.

Pada hari-hari awal ARPAnet, protokol tertentu (FTP untuk satu) akan mendengarkan port tertentu untuk permintaan koneksi, dan membalas dengan port handoff. Komunikasi lebih lanjut untuk koneksi itu akan melewati port handoff. Ini dilakukan untuk meningkatkan kinerja per paket: komputer beberapa kali lipat lebih lambat pada masa itu.


sumber
dapatkah Anda menguraikan bagian 'handoff port'?
Eli Bendersky
1
Ini adalah deskripsi dari beberapa protokol pra-TCP, atau terlalu disederhanakan. Seorang klien mencoba untuk menyambung ke soket mendengarkan mengirimkan paket khusus untuk membuat koneksi (set SYN bit). Ada perbedaan yang jelas antara paket yang membuat soket baru dan paket yang menggunakan soket yang ada.
John M
... mengirimkan paket khusus untuk membuat koneksi (set bit SYN). Yang (seperti yang saya pahami) menyebabkan tumpukan protokol memberikannya kepada 'pendengar' (jika ada) itulah sebabnya hanya ada satu port mendengarkan per kombinasi alamat / port / protokol. Saya tidak yakin apakah ini ada dalam spesifikasi atau hanya konvensi implementasi.
Peter Wone
1
Paragraf kedua tidak menjelaskan dengan benar apa yang terjadi baik di lapisan TCP atau dalam proses server. Proses server tidak perlu memelihara struktur data soket dalam bentuk apa pun, atau untuk memeriksa IP yang masuk: pasangan port terhadap apa pun. Untuk itulah ada soket. FTP menggunakan port terpisah untuk data, bukan untuk semua 'komunikasi lebih lanjut', dan topi dilakukan untuk menyederhanakan protokol, bukan untuk alasan kinerja. Menggunakan port baru namun tidak meningkatkan kinerja dengan cara apa pun.
Marquis dari Lorne
"memelihara database (artinya saya tidak peduli jenis tabel / daftar / pohon / larik / struktur data ajaib yang digunakannya)" :) Saya biasanya menyebutnya "Tabel" (atau mungkin "Grafik" atau "Pohon keputusan" ). "Database" menyarankan beberapa implementasi kepada saya.
masterxilo