回答:
考えられるOSによって答えは異なります。一般的にはしかし:
TCPの場合、違います。同じポートで同時にリッスンできるアプリケーションは1つだけです。2つのネットワークカードがある場合、同じポート番号を使用して、1つのアプリケーションで最初のIPをリッスンし、2番目のアプリケーションで2番目のIPをリッスンすることができます。
UDP(マルチキャスト)の場合、複数のアプリケーションが同じポートにサブスクライブできます。
編集:Linuxカーネル3.9以降では、同じポートをリッスンする複数のアプリケーションのサポートがSO_REUSEPORT
オプションを使用して追加されました。詳細については、このlwn.netの記事を参照してください。
はい(TCPの場合)、プログラムがそのように設計されている場合、2つのプログラムが同じソケットでリッスンできるようにすることができます。最初のプログラムでソケットが作成されたら、SO_REUSEADDR
オプションがソケットに設定されていることを確認してから、を実行してくださいbind()
。しかし、これはあなたが望むものではないかもしれません。これが行うことは、着信TCP接続が両方ではなくプログラムの1つに向けられるため、接続を複製せず、2つのプログラムが着信要求にサービスを提供できるようにするだけです。たとえば、Webサーバーにはすべてポート80でリッスンする複数のプロセスがあり、O / Sは新しい接続を受け入れる準備ができているプロセスに新しい接続を送信します。
SO_REUSEADDR
bind()
すでにポートにバインドされているアクティブなリスニングソケットがない限り、他のソケットがこのポートに接続できるようにします。これにより、クラッシュ後にサーバーを再起動しようとしたときに、「使用中のアドレス」エラーメッセージを回避できます。
SO_REUSEADDR
確かに、少なくともUnixでは、同時に2つのTCPソケットをリスニング状態にすることはできません。これは、unixguide.netTIME_WAIT state
/ network / socketfaq / 4.5.shtmlを回避するためのものです。Windowsでも機能する可能性がありますが、リクエストが正しいサーバーに到達することは保証されません)。
はい。
同じポートにバインドされている複数のリスニングTCPソケットは、それらがすべて異なるローカルIPアドレスにバインドされている場合、共存できます。クライアントは必要な方に接続できます。これには0.0.0.0
(INADDR_ANY
)は含まれません。
複数の受け入れられたソケットは共存でき、すべて同じリスニングソケットから受け入れられ、すべてリスニングソケットと同じローカルポート番号を示します。
同じポートにバインドされた複数のUDPソケットは、(1)と同じ条件が提供されるか、SO_REUSEADDR
バインド前にすべてオプションが設定されていれば、すべて共存できます。
TCPポートとUDPポートは異なる名前空間を使用するため、TCPにポートを使用しても、UDPを使用できなくなることはなく、その逆も同様です。
参照:Stevens&Wright、TCP / IP Illustrated、 Volume II。
原則として、違います。
それは石で書かれていません。しかし、これはすべてのAPIの記述方法です。アプリはポートを開き、ハンドルを取得します。クライアント接続(またはUDPの場合はパケット)が到着すると、OSは(そのハンドルを介して)ポートに通知します。
OSが2つのアプリに同じポートを開くことを許可した場合、どのアプリに通知するかをどのようにして知るのでしょうか
しかし...それを回避する方法があります:
iptables -m statistic --mode random --probability 0.5
楽しいです。
listen()
。おそらく問題はファイアウォールでそれを開くことです。ここでは非常に多くのエラーがあり、7年間はすべて修正されていません。Answerは、同じポート番号を持つ異なるローカルアドレスにバインドする場合も省略します。それは実際には完全に間違っています。
はいもちろんです。私が覚えている限り、カーネルバージョン3.9(バージョンは不明)以降では、のサポートSO_REUSEPORT
が導入されました。SO_RESUEPORT
最初のサーバーがこのオプションを設定してからソケットをバインドする限り、まったく同じポートとアドレスにバインドできます。
TCPとUDPの両方で機能します。詳細については、リンクを参照してください:SO_REUSEPORT
注:私の意見では、受け入れられた回答はもはや真実ではありません。
いいえ。一度にポートにバインドできるアプリケーションは1つだけであり、バインドが強制された場合の動作は不確定です。
マルチキャストソケット(希望するものに近いとは思えない)の場合、各ソケットのオプションでSO_REUSEADDRが設定されている限り、複数のアプリケーションがポートにバインドできます。
これは、すべての接続を受け入れて処理する「マスター」プロセスを記述し、同じポートでリッスンする必要がある2つのアプリケーションにそれらを引き渡すことで実現できます。多くのプロセスが80をリッスンする必要があるため、これはWebサーバーなどが採用するアプローチです。
これ以外にも、詳細について調べています-TCPとUDPの両方にタグを付けましたが、それは何ですか?また、どのプラットフォームですか?
別の方法は、1つのポートでリッスンするプログラムを使用して、「実際の」サービスがリッスンしている別のポートに内部的にリダイレクトするトラフィックの種類(ssh、httpsなど)を分析することです。
たとえば、Linuxの場合、sslh:https : //github.com/yrutschle/sslh
TCP接続を作成するときは、IPアドレス(使用しているプロトコルに応じてv4またはv6)とポートを組み合わせた特定のTCPアドレスに接続するように求めます。
サーバーが接続をリッスンするとき、特定のIPアドレスとポート、つまり1つのTCPアドレス、または各ホストのIPアドレス(通常はIPアドレスで指定)の同じポートをリッスンすることをカーネルに通知できます0.0.0.0
)、効果的に異なる「TCPアドレス」(例えば、多くの上で待機している192.168.1.10:8000
、127.0.0.1:8000
など)
いいえ、2つのアプリケーションが同じ「TCPアドレス」をリッスンすることはできません。メッセージが届いたときに、カーネルはどのアプリケーションにメッセージを送るかをどのようにして知るのでしょうか。
ただし、ほとんどのオペレーティングシステムでは、1つのインターフェースに複数のIPアドレスを設定できます(たとえば、192.168.1.10
インターフェース上にある192.168.1.11
場合、ネットワーク上の他のユーザーがそれを使用していない場合は、を設定することもできます)。8000
これら2つのIPアドレスのそれぞれのポートでリッスンする個別のアプリケーションを使用できます。
はいといいえ。1つのアプリケーションだけがポートをアクティブにリッスンできます。しかし、そのアプリケーションは別のプロセスへの接続を継承する可能性があります。したがって、同じポートで複数のプロセスが動作する可能性があります。
@jnewtonが言ったことを共有するだけです。Macでnginxと組み込みのTomcatプロセスを開始しました。両方のプロセスが8080で実行されているのがわかります。
LT<XXXX>-MAC:~ b0<XXX>$ sudo netstat -anp tcp | grep LISTEN
tcp46 0 0 *.8080 *.* LISTEN
tcp4 0 0 *.8080 *.* LISTEN
短い答え:
ここで与えられた答えで行く。同じIPアドレスとポート番号で2つのアプリケーションをリッスンすることができます。そのため、ポートの一方がUDPポートであり、もう一方がTCPポートです。
説明:
ポートの概念はTCP / IPスタックのトランスポート層に関連するため、スタックの異なるトランスポート層プロトコルを使用している限り、同じ<ip-address>:<port>
組み合わせで複数のプロセスがリッスンすることができます。
2つのアプリケーションが同じ<ip-address>:<port>
組み合わせで実行されている場合、リモートマシンで実行されているクライアントは2つをどのように区別するのでしょうか。IPレイヤーパケットヘッダー(https://en.wikipedia.org/wiki/IPv4#Header)を見ると、プロトコルの定義にビット72〜79が使用されていることがわかります。これにより、区別を行うことができます。
ただし、同じTCPの<ip-address>:<port>
組み合わせで2つのアプリケーションを使用したい場合、答えは「いいえ」です(興味深い演習では、2つのVMを起動し、それらに同じIPアドレスを与えますが、異なるMACアドレスを与え、何が起こるかを確認します-時々気づくでしょうVM1はパケットを取得し、それ以外の場合はVM2がパケットを取得します(ARPキャッシュの更新によって異なります)。
2つのアプリケーションを同じ上で実行<op-address>:<port>
することで、ある種のロードバランシングを実現したいと思います。このため、異なるポートでアプリケーションを実行し、IPテーブルルールを記述して、ポート間のトラフィックを分岐させることができます。
@ user6169806の回答もご覧ください。