TCP / HTTP Mendengarkan Pada Port: Bagaimana Banyak Pengguna Dapat Berbagi Port Yang Sama
Jadi, apa yang terjadi ketika server mendengarkan koneksi masuk pada port TCP? Misalnya, Anda memiliki server web pada port 80. Anggaplah komputer Anda memiliki alamat IP publik 24.14.181.229 dan orang yang mencoba menyambung ke Anda memiliki alamat IP 10.1.2.3. Orang ini dapat terhubung dengan Anda dengan membuka soket TCP ke 24.14.181.229:80. Cukup sederhana.
Secara intuitif (dan salah), kebanyakan orang berasumsi bahwa tampilannya seperti ini:
Local Computer | Remote Computer
--------------------------------
<local_ip>:80 | <foreign_ip>:80
^^ not actually what happens, but this is the conceptual model a lot of people have in mind.
Ini intuitif, karena dari sudut pandang klien, dia memiliki alamat IP, dan terhubung ke server di IP: PORT. Karena klien terhubung ke port 80, maka portnya juga harus 80? Ini adalah hal yang masuk akal untuk dipikirkan, tetapi sebenarnya bukan apa yang terjadi. Jika itu benar, kami hanya dapat melayani satu pengguna per alamat IP asing. Setelah komputer jarak jauh terhubung, maka dia akan memonopoli koneksi port 80 ke port 80, dan tidak ada orang lain yang dapat terhubung.
Tiga hal yang harus dipahami:
1.) Di server, proses sedang mendengarkan di port. Setelah mendapat koneksi, itu menyerahkannya ke utas lain. Komunikasi tidak pernah membebani port mendengarkan.
2.) Koneksi dikenali secara unik oleh OS dengan 5-tuple berikut: (local-IP, local-port, remote-IP, remote-port, protocol). Jika ada elemen dalam tupel yang berbeda, maka ini adalah koneksi yang sepenuhnya independen.
3.) Ketika klien terhubung ke server, ia mengambil port sumber tingkat tinggi acak yang tidak terpakai . Dengan cara ini, satu klien dapat memiliki hingga ~ 64k koneksi ke server untuk port tujuan yang sama.
Jadi, inilah yang sebenarnya dibuat ketika klien terhubung ke server:
Local Computer | Remote Computer | Role
-----------------------------------------------------------
0.0.0.0:80 | <none> | LISTENING
127.0.0.1:80 | 10.1.2.3:<random_port> | ESTABLISHED
Melihat Apa yang Sebenarnya Terjadi
Pertama, mari gunakan netstat untuk melihat apa yang terjadi di komputer ini. Kami akan menggunakan port 500, bukan 80 (karena banyak hal terjadi pada port 80 karena ini adalah port yang umum, tetapi secara fungsional tidak membuat perbedaan).
netstat -atnp | grep -i ":500 "
Seperti yang diharapkan, hasilnya kosong. Sekarang mari kita mulai server web:
sudo python3 -m http.server 500
Sekarang, inilah hasil dari menjalankan netstat lagi:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
Jadi sekarang ada satu proses yang aktif mendengarkan (Status: LISTEN) pada port 500. Alamat lokalnya adalah 0.0.0.0, yang merupakan kode untuk "mendengarkan semua alamat ip". Kesalahan yang mudah dilakukan adalah hanya mendengarkan pada port 127.0.0.1, yang hanya akan menerima koneksi dari komputer saat ini. Jadi ini bukan koneksi, ini hanya berarti bahwa proses diminta untuk mengikat () ke port IP, dan proses tersebut bertanggung jawab untuk menangani semua koneksi ke port tersebut. Ini mengisyaratkan batasan bahwa hanya ada satu proses per komputer yang mendengarkan pada port (ada cara untuk menyiasatinya menggunakan multiplexing, tetapi ini adalah topik yang jauh lebih rumit). Jika server web mendengarkan pada port 80, itu tidak dapat berbagi port itu dengan server web lain.
Jadi sekarang, mari hubungkan pengguna ke mesin kita:
quicknet -m tcp -t localhost:500 -p Test payload.
Ini adalah skrip sederhana ( https://github.com/grokit/quickweb ) yang membuka soket TCP, mengirim payload ("Uji payload". Dalam hal ini), menunggu beberapa detik dan memutuskan hubungan. Melakukan netstat lagi saat ini terjadi akan menampilkan berikut ini:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:54240 ESTABLISHED -
Jika Anda terhubung dengan klien lain dan melakukan netstat lagi, Anda akan melihat yang berikut ini:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:500 0.0.0.0:* LISTEN -
tcp 0 0 192.168.1.10:500 192.168.1.13:26813 ESTABLISHED -
... yaitu, klien menggunakan port acak lain untuk koneksi tersebut. Jadi tidak pernah ada kebingungan antara alamat IP.