sockets - 複数ソケット - 同一ポート 複数プロセス




2つのアプリケーションが同じポートを聞くことはできますか? (11)

1つのネットワークインターフェイスに対して、1つのポートで1つのアプリケーションをリッスンすることができます。 したがって、あなたは以下を持つことができます:

  1. 遠隔アクセス可能なインタフェースでリッスンするhttpd 、例えば192.168.1.1:80
  2. 127.0.0.1:80リッスンしている別のデーモン

サンプルユースケースは、 httpdをロードバランサまたはプロキシとして使用することです。

同じマシン上の2つのアプリケーションを同じポートとIPアドレスにバインドできますか? それをさらに進めていくと、特定のIPからのリクエストと別のIPからのリクエストを1つのアプリが聞くことができますか? 私は、2つのスレッド(またはフォーク)から同様の動作を開始する1つのアプリケーションを持つことはできますが、共通のものを持たない2つのアプリケーションは同じことを行うことができますか?


2つのアプリケーションが同じネットワークインターフェイス上の同じポートを受信するようにすることができます。

指定されたネットワークインターフェイスとポートに対して1つのリスニングソケットしか存在できませんが、そのソケットは複数のアプリケーション間で共有できます。

アプリケーションプロセス内にリスニングソケットがあり、そのプロセスをforkすると、ソケットは継承されるため、技術的には同じポートをリッスンする2つのプロセスが存在します。


TCP接続を作成するときは、特定のTCPアドレスに接続するかどうかを尋ねます。これは、使用しているプロトコルに応じて、IPアドレス(v4またはv6)とポートの組み合わせです。

サーバが接続をリッスンすると、特定のIPアドレスとポート、つまり1つのIPアドレス、または特定のポート上のすべてのホストIPアドレスを聴きたいとカーネルに通知することができますさまざまな "TCPアドレス"(192.168.1.10:8000、127.0.0.1:8000など)をたくさん聞いて、

いいえ、同じ "TCPアドレス"でリッスンする2つのアプリケーションを持つことはできません。なぜなら、メッセージが届くと、カーネルはどのアプリケーションにメッセージを伝えるべきかを知っているからです。

しかし、ほとんどのオペレーティングシステムでは、1つのインターフェイスに複数のIPアドレスを設定できます(たとえば、インターフェイスに192.168.1.10がある場合、ネットワーク上の他の誰もそれを使用していない場合は192.168.1.11を設定することもできます)そのような場合、2つのIPアドレスのそれぞれでポート8000​​でリスンするアプリケーションを別々に持つことができます。


はい間違いなく 。 私が覚えている限り、カーネルバージョン3.9(バージョンではわからない)以降、 SO_REUSEPORTサポートが導入されました。 SO_RESUEPORTは、まったく同じポートとアドレスへのバインドを許可します。最初のサーバーがソケットをバインドする前にこのオプションを設定している限りです。

TCPUDPの両方で動作します 。 詳細はリンクを参照してください: SO_REUSEPORT

:受け入れられた答えは、もはや私の意見では当てはまりません。


いいえ。一度に1つのアプリケーションだけがポートにバインドできます。バインドが強制された場合の動作は不確定です。

あなたが望むものの近くにいないようなマルチキャストソケットでは、各ソケットのオプションにSO_REUSEADDRが設定されている限り、複数のアプリケーションをポートにバインドすることができます。

これを達成するには、すべての接続を受け入れて処理する「マスター」プロセスを作成し、同じポートでリスンする必要のある2つのアプリケーションにそれらを渡します。 これは、多くのプロセスが80を聞く必要があるため、Webサーバーなどが採用するアプローチです。

これ以外にも、TCPとUDPの両方をタグ付けした具体的な内容になっています。 また、どのプラットフォームですか?


はい。

  1. すべて同じポートにバインドされた複数のリッスンTCPソケットは、すべてが異なるローカルIPアドレスにバインドされていれば、共存することができます。 クライアントは、必要なものに接続できます。 0.0.0.0INADDR_ANY )は除外されINADDR_ANY

  2. 複数の受け入れ可能なソケットが共存することができ、すべてが同じ待機ソケットから受け入れられ、すべてが待機ソケットと同じローカルポート番号を示します。

  3. 同じポートにバインドされた複数のUDPソケットは、(1)と同じ条件で提供されるか、すべてバインディング前にSO_REUSEADDRオプションが設定されています。

  4. TCPポートとUDPポートは異なる名前空間を占めます。そのため、TCPにポートを使用しても、そのポートでUDPを使用することはできません

参考文献:Stevens&Wright、 TCP / IP Illustrated、第II巻。


はいといいえ。 1つのポート上でアクティブにリスンできるアプリケーションは1つだけです。 しかし、そのアプリケーションは別のプロセスとの接続を維持することができます。 そのため、同じポートで複数のプロセスを動作させることができます。


もう1つの方法は、ある種のトラフィック(ssh、httpsなど)を分析する1つのポートをリッスンするプログラムを使用して、「実際の」サービスがリスンしている別のポートに内部的にリダイレクトします。

たとえば、Linuxの場合、sslh: https://github.com/yrutschle/sslh : https://github.com/yrutschle/sslh


原則として、いいえ。

それは石で書かれていません。 それはすべてのAPIが書かれている方法です:アプリケーションはポートを開き、ハンドルを取得し、OSはクライアント接続(またはUDPの場合はパケット)が到着したときにそのハンドルを介して通知します。

OSが2つのアプリケーションで同じポートを開くことを許可した場合、どのポートに通知するかはどのように分かりますか?

しかし、そこには方法があります:

  1. Jedがnoted 、あなたは本当にポートで待機し、他の人に通知する唯一のプロセスである「マスタ」プロセスを作成し、クライアント要求を分離するロジックを使用することができます。
    • LinuxとBSD(少なくとも)では、ネットワークに関連する基準(多分元々のネットワーク、またはいくつかのネットワーク)にしたがって、パケットを「可視」ポートから別のもの(アプリケーションがリッスンしている)にリダイレクトする「再マッピング」ルールを設定できますロードバランシングの単純な形式)。

少なくとも1つのリモートIPが既に知られていて静的で、あなたのアプリケーションの1つにしか話せない場合は、iptablesルール(table nat、チェーンPREROUTING)を使用して、このアドレスから "共有"ローカルポート適切なアプリケーションが実際にリスンする他のポート。


はい(TCPの場合)は、プログラムがそうするように設計されている場合、2つのプログラムを同じソケットでリッスンさせることができます。 最初のプログラムでソケットを作成するときは、 bind()前にソケットにSO_REUSEADDRオプションが設定されていることを確認してSO_REUSEADDR 。 しかし、これはあなたが望むものではないかもしれません。 これは、入ってくるTCP接続が両方のプログラムではなく、いずれかのプログラムに送られるため、接続を複製しないので、2つのプログラムが着信要求を処理することができます。 たとえば、Webサーバーでは、すべてポート80で待機している複数のプロセスがあり、O / Sは新しい接続を受け入れる準備ができているプロセスに新しい接続を送信します。

SO_REUSEADDR

既にポートにバインドされているアクティブなリスニングソケットがない限り、他のソケットがこのポートにbind()ようにします。 これにより、クラッシュ後にサーバーを再起動しようとすると、「Address already in use」エラーメッセージが表示されます。





communication