Bisakah dua aplikasi pada mesin yang sama mengikat ke port dan alamat IP yang sama? Melangkah lebih jauh, dapatkah satu aplikasi mendengarkan permintaan yang datang dari IP tertentu dan yang lainnya ke IP jarak jauh lainnya? Saya tahu saya dapat memiliki satu aplikasi yang dimulai dari dua utas (atau garpu) untuk memiliki perilaku yang sama, tetapi dapatkah dua aplikasi yang tidak memiliki kesamaan melakukan hal yang sama?
283
Jawaban:
Jawabannya berbeda tergantung pada OS apa yang dipertimbangkan. Secara umum:
Untuk TCP, tidak. Anda hanya dapat memiliki satu aplikasi mendengarkan pada port yang sama sekaligus. Sekarang jika Anda memiliki 2 kartu jaringan, Anda dapat meminta satu aplikasi mendengarkan pada IP pertama dan yang kedua pada IP kedua menggunakan nomor port yang sama.
Untuk UDP (Multicast), beberapa aplikasi dapat berlangganan ke port yang sama.
Sunting: Sejak Linux Kernel 3.9 dan yang lebih baru, dukungan untuk beberapa aplikasi yang mendengarkan port yang sama ditambahkan menggunakan
SO_REUSEPORT
opsi. Informasi lebih lanjut tersedia di artikel lwn.net ini.sumber
Ya (untuk TCP) Anda dapat meminta dua program mendengarkan pada soket yang sama, jika program dirancang untuk melakukannya. Ketika soket dibuat oleh program pertama, pastikan
SO_REUSEADDR
opsi sudah diatur pada soket sebelum Andabind()
. Namun, ini mungkin bukan yang Anda inginkan. Apa yang dilakukan adalah koneksi TCP yang masuk akan diarahkan ke salah satu program, bukan keduanya, sehingga tidak menggandakan koneksi, itu hanya memungkinkan dua program untuk melayani permintaan yang masuk. Misalnya, server web akan memiliki beberapa proses yang semuanya mendengarkan pada port 80, dan O / S mengirim koneksi baru ke proses yang siap menerima koneksi baru.Mengizinkan soket lain ke
bind()
port ini, kecuali jika sudah ada soket mendengarkan aktif yang terikat ke port. Ini memungkinkan Anda untuk menghindari pesan-pesan kesalahan "Alamat yang sudah digunakan" ketika Anda mencoba untuk me-restart server Anda setelah crash.sumber
SO_REUSEADDR
tentu saja tidak membiarkan Anda memiliki dua soket TCP dalam kondisi mendengarkan pada saat yang sama, setidaknya di Unix. Ini dimaksudkan untuk berkelilingTIME_WAIT state
: unixguide.net/network/socketfaq/4.5.shtml . Ini mungkin bekerja pada Windows, tetapi Anda tidak dijamin bahwa permintaan akan mencapai server yang benar).Iya.
Beberapa soket TCP yang mendengarkan, semuanya terikat ke port yang sama, dapat hidup berdampingan, asalkan semuanya terikat ke alamat IP lokal yang berbeda. Klien dapat terhubung ke mana pun mereka perlu. Ini tidak termasuk
0.0.0.0
(INADDR_ANY
).Beberapa soket yang diterima dapat hidup berdampingan, semua diterima dari soket pendengaran yang sama, semua menunjukkan nomor port lokal yang sama dengan soket pendengaran.
Beberapa soket UDP semua terikat pada port yang sama dapat semuanya hidup berdampingan dengan ketentuan yang sama seperti pada (1) atau semuanya memiliki
SO_REUSEADDR
opsi yang ditetapkan sebelum mengikat.Port TCP dan port UDP menempati ruang nama yang berbeda, sehingga penggunaan port untuk TCP tidak menghalangi penggunaannya untuk UDP, dan sebaliknya.
Referensi: Stevens & Wright, Illustrated TCP / IP, Volume II.
sumber
Pada prinsipnya tidak.
Itu tidak ditulis dalam batu; tapi begitulah cara semua API ditulis: aplikasi membuka port, menanganinya, dan OS memberitahukannya (melalui pegangan itu) ketika koneksi klien (atau paket dalam kasus UDP) tiba.
Jika OS mengizinkan dua aplikasi untuk membuka port yang sama, bagaimana ia tahu mana yang harus diberitahukan?
Tapi ... ada beberapa cara mengatasinya:
sumber
iptables -m statistic --mode random --probability 0.5
menyenangkan.listen()
. Lebih mungkin pertanyaannya adalah tentang membukanya di firewall. Terlalu banyak kesalahan di sini, dan semuanya tidak diperbaiki dalam 7 tahun. Jawaban juga menghilangkan kasus pengikatan ke alamat lokal yang berbeda dengan nomor port yang sama. Ini sebenarnya sama sekali tidak benar.Ya pasti . Sejauh yang saya ingat Dari kernel versi 3.9 (Tidak yakin pada versi) dan seterusnya dukungan untuk
SO_REUSEPORT
diperkenalkan.SO_RESUEPORT
memungkinkan pengikatan ke port dan alamat yang sama persis, Selama server pertama menetapkan opsi ini sebelum mengikat soketnya.Ini berfungsi untuk TCP dan UDP . Lihat tautan untuk detail lebih lanjut: SO_REUSEPORT
Catatan : Jawaban yang diterima tidak lagi berlaku menurut pendapat saya.
sumber
Tidak. Hanya satu aplikasi yang dapat mengikat ke port pada satu waktu, dan perilaku jika ikatan dipaksa tidak dapat ditentukan.
Dengan soket multicast - yang kedengarannya sama sekali tidak seperti yang Anda inginkan - lebih dari satu aplikasi dapat mengikat ke port selama SO_REUSEADDR diatur di setiap opsi soket.
Anda bisa menyelesaikan ini dengan menulis proses "master", yang menerima dan memproses semua koneksi, kemudian menyerahkannya ke dua aplikasi Anda yang perlu mendengarkan pada port yang sama. Ini adalah pendekatan yang diambil oleh server Web dan semacamnya, karena banyak proses perlu mendengarkan 80.
Di luar ini, kami sedang membahas spesifik - Anda menandai TCP dan UDP, yang mana? Juga, platform apa?
sumber
Anda dapat memiliki satu aplikasi mendengarkan pada satu port untuk satu antarmuka jaringan. Karena itu Anda dapat memiliki:
httpd
mendengarkan pada antarmuka yang dapat diakses dari jarak jauh, mis192.168.1.1:80
127.0.0.1:80
Contoh use case bisa digunakan
httpd
sebagai load balancer atau proxy.sumber
Cara lain adalah menggunakan program mendengarkan dalam satu port yang menganalisis jenis lalu lintas (ssh, https, dll) yang dialihkan secara internal ke port lain di mana layanan "nyata" mendengarkan.
Misalnya, untuk Linux, sslh: https://github.com/yrutschle/sslh
sumber
Saat Anda membuat koneksi TCP, Anda meminta untuk terhubung ke alamat TCP tertentu, yang merupakan kombinasi dari alamat IP (v4 atau v6, tergantung pada protokol yang Anda gunakan) dan port.
Ketika server mendengarkan koneksi, ia dapat memberitahu kernel bahwa ia ingin mendengarkan alamat IP dan port tertentu, yaitu, satu alamat TCP, atau pada port yang sama pada masing-masing alamat IP host (biasanya ditentukan dengan alamat IP
0.0.0.0
), yang secara efektif mendengarkan banyak "alamat TCP" yang berbeda (mis192.168.1.10:8000
.127.0.0.1:8000
,, dll.)Tidak, Anda tidak dapat memiliki dua aplikasi yang mendengarkan "alamat TCP" yang sama, karena ketika sebuah pesan masuk, bagaimana kernel tahu aplikasi mana yang memberikan pesan?
Namun, Anda di sebagian besar sistem operasi, Anda dapat mengatur beberapa alamat IP pada satu antarmuka (misalnya, jika Anda memiliki
192.168.1.10
pada suatu antarmuka, Anda juga dapat mengatur192.168.1.11
, jika tidak ada orang lain di jaringan yang menggunakannya), dan dalam kasus tersebut Anda dapat memiliki aplikasi terpisah mendengarkan pada port8000
pada masing-masing dua alamat IP tersebut.sumber
Jika setidaknya salah satu IP jarak jauh sudah dikenal, statis dan didedikasikan untuk berbicara hanya dengan salah satu aplikasi Anda, Anda dapat menggunakan aturan iptables (tabel nat, chain PREROUTING) untuk mengarahkan lalu lintas incomming dari alamat ini ke port lokal "shared" ke port lain di mana aplikasi yang sesuai benar-benar mendengarkan.
sumber
Iya dan tidak. Hanya satu aplikasi yang dapat secara aktif mendengarkan pada port. Tetapi aplikasi itu dapat mewariskan koneksinya ke proses lain. Jadi Anda bisa memiliki beberapa proses yang bekerja pada port yang sama.
sumber
Iya.
Dari artikel ini:
https://lwn.net/Articles/542629/
sumber
Jika dengan aplikasi yang Anda maksud beberapa proses maka ya tetapi umumnya TIDAK. Misalnya server Apache menjalankan beberapa proses pada port yang sama (umumnya 80). Hal ini dilakukan dengan menunjuk salah satu proses untuk benar-benar mengikat ke port dan kemudian menggunakan proses itu untuk melakukan penyerahan ke berbagai proses yang menerima koneksi.
sumber
Anda dapat membuat dua aplikasi mendengarkan port yang sama pada antarmuka jaringan yang sama.
Hanya ada satu soket pendengar untuk antarmuka dan port jaringan yang ditentukan, tetapi soket itu dapat dibagi antara beberapa aplikasi.
Jika Anda memiliki soket pendengaran dalam proses aplikasi dan Anda
fork
proses itu, soket akan diwarisi, jadi secara teknis sekarang akan ada dua proses mendengarkan port yang sama.sumber
Saya sudah mencoba yang berikut ini, dengan
socat
:Dan meskipun saya belum membuat koneksi ke soket, saya tidak bisa mendengarkan dua kali pada port yang sama, terlepas dari
reuseaddr
opsi.Saya mendapatkan pesan ini (yang saya harapkan sebelumnya):
sumber
Hanya untuk membagikan apa yang @jnewton sebutkan. Saya memulai nginx dan proses tomcat tertanam pada mac saya. Saya bisa melihat kedua proses runninng di 8080.
sumber
Jawaban singkat:
Pergi dengan jawaban yang diberikan di sini . Anda dapat memiliki dua aplikasi mendengarkan pada alamat IP yang sama, dan nomor port, begitu lama salah satu port adalah port UDP, sementara yang lain adalah port TCP.
Penjelasan:
Konsep port relevan pada lapisan transport dari TCP / IP stack, sehingga selama Anda menggunakan protokol transport layer yang berbeda dari stack, Anda dapat memiliki banyak proses mendengarkan pada
<ip-address>:<port>
kombinasi yang .Satu keraguan yang dimiliki orang adalah jika dua aplikasi berjalan pada
<ip-address>:<port>
kombinasi yang sama , bagaimana klien yang berjalan pada mesin jarak jauh membedakan antara keduanya? Jika Anda melihat header paket lapisan IP ( https://en.wikipedia.org/wiki/IPv4#Header ), Anda akan melihat bahwa bit 72 hingga 79 digunakan untuk mendefinisikan protokol, ini adalah bagaimana perbedaan dapat dibuat.Namun jika Anda ingin memiliki dua aplikasi pada
<ip-address>:<port>
kombinasi TCP yang sama , maka jawabannya adalah tidak (Latihan yang menarik akan meluncurkan dua VM, berikan mereka alamat IP yang sama, tetapi alamat MAC yang berbeda, dan lihat apa yang terjadi - Anda akan memperhatikan bahwa beberapa kali VM1 akan mendapatkan paket, dan lain kali VM2 akan mendapatkan paket - tergantung pada penyegaran cache ARP).Saya merasa bahwa dengan membuat dua aplikasi berjalan pada saat yang sama
<op-address>:<port>
Anda ingin mencapai semacam penyeimbangan beban. Untuk ini, Anda dapat menjalankan aplikasi pada port yang berbeda, dan menulis aturan tabel IP untuk membagi dua lalu lintas di antara mereka.Juga lihat jawaban @ user6169806.
sumber