2

各プロセスが異なるポートを選択してソケットを作成し、別のマシンと通信するように、マシン上でいくつかのプロセスを相互に調整する必要があります。各プロセスは、任意の時点で 1 つのプロセスだけが特定のポート番号を使用するように、使用可能なポートの範囲からポート番号を選択する必要があります。

この調整を行うための既存のメカニズムはありますか、それとも独自に構築する必要がありますか?

現在、ディスク上のファイルを使用して、ポート番号とそのポートを使用している PID を登録しています。PID が実行されていないエントリが見つかった場合、プロセスが正常に終了していないと見なされ、そのエントリをリープする必要があるため、そのエントリは削除されます。

ただし、まれに、ある種の競合状態があるようです。同じポートを使用する 2 つのプロセスが発生し、2 番目のプロセスはポートが予約されていることを示すファイルの内容を認識せず、2 回目に使用することになります。

これを修正するよりも、このポートの衝突を回避するための既存のメカニズムを採用したいので、そのようなユーティリティが既に存在するかどうかを尋ねています。

4

1 に答える 1

1

TCP または UDP と通信する場合、ソケットは 4 つのタプルによって区別されます。

  • ローカルアドレス
  • ローカル ポート
  • リモートアドレス
  • リモートポート

ローカル割り当てをそのままにして、接続されたプロトコルと通信している場合、connect呼び出しは使用可能なローカル ポートを見つけます。特定の範囲のポートに制限されている場合は、ローカル アドレスとポート バインディングを行う必要があります。ただし、その場合、各プロセスは単一の接続しか処理しないため、使用可能なポートを見つけようとするのではなく、開始時に各プロセスに一意のポートを割り当てるだけです。

つまり、他のすべてのプロセスの開始を担当する単一のプロセスがあると仮定すると、その単一のプロセスが、開始しようとしているプロセスが使用するポートを決定します。決定は単一のエンティティによって行われるため、これはより単純であり、次のような単純なアルゴリズムを使用できます。

for (unsigned short p = minPort; p < maxPort; ++p) {
    child_pid = startWorker(p);
    child_pid_map[child_pid] = p;
}

子プロセスが停止した場合、スターター プロセスは を参照して、child_pid_mapそのポートをすぐに再利用できます。

外部エージェントを使用してポートを割り当てることができない場合、最も簡単な方法はbind、範囲内のランダムなポートへの呼び出しを試みることです。で失敗した場合はEADDRINUSE、成功するまで、またはすべてのポートを試すまで、シーケンス内の次のポート番号を段階的に試行します (必要に応じてラップします)。

于 2012-06-10T10:15:02.790 に答える