私は簡単なクライアントサーバーアプリを書いていますが、それは当分の間、私自身の個人的な使用になります。ネット通信にWinsockを使用しています。私は過去10年間ネットワーキングを行っていないので、かなり錆びています。外部コードをできるだけ少なくしたいので、次のように自家製のサーバー検出メカニズムを作成しました。
クライアントは、任意のポートにバインドされたクライアントUDPソケットの「名前」を含むメッセージをブロードキャストします。これをクライアントの検出ソケットと呼びます。サーバーはブロードキャストをrecv()し、次にクライアント検出ソケットにそのリスニングソケットの「名前」をsendto()します。次に、クライアントはこの情報を使用して(別のソケット上の)サーバーに接続します。このメカニズムにより、サーバーはリスニングソケットを動的ポート範囲(49152〜65535)内の最初のポートにバインドし、クライアントがサーバーの場所とリッスンしているポートを検出できるようにする必要があります。
サーバー部分は正常に機能します。サーバーはブロードキャストメッセージを受信し、応答を正常に送信します。
クライアント側では、ファイアウォールログは、サーバーの応答がマシンに到着し、それが正しいポート(クライアントの検出ソケット)にアドレス指定されていることを示しています。ただし、メッセージがクライアントアプリに届くことはありません。ブロッキングモードと非ブロッキングモードでrecv()を実行しようとしましたが、使用可能なデータがありません。ioctlsocket()は、パケットがマシンにデータを取得したことを知っていても、常に利用可能なデータがないことを示します。
サーバーは、ブロードキャストされたデータに対してrecv()を実行することに成功します。ただし、クライアントは、検出ソケットにアドレス指定されたサーバーの応答のrecv()の実行に失敗します。
質問は非常にあいまいです。このシナリオでは、どのような落とし穴に注意する必要がありますか?recv()が実際にマシンに到着したパケットを取得できないのはなぜですか?ソケットはUDPであるため、接続されていないという事実は関係ありません。またはそれは?
よろしくお願いします。