0

私は簡単なクライアントサーバーアプリを書いていますが、それは当分の間、私自身の個人的な使用になります。ネット通信にWinsockを使用しています。私は過去10年間ネットワーキングを行っていないので、かなり錆びています。外部コードをできるだけ少なくしたいので、次のように自家製のサーバー検出メカニズムを作成しました。

クライアントは、任意のポートにバインドされたクライアントUDPソケットの「名前」を含むメッセージをブロードキャストします。これをクライアントの検出ソケットと呼びます。サーバーはブロードキャストをrecv()し、次にクライアント検出ソケットにそのリスニングソケットの「名前」をsendto()します。次に、クライアントはこの情報を使用して(別のソケット上の)サーバーに接続します。このメカニズムにより、サーバーはリスニングソケットを動的ポート範囲(49152〜65535)内の最初のポートにバインドし、クライアントがサーバーの場所とリッスンしているポートを検出できるようにする必要があります。

サーバー部分は正常に機能します。サーバーはブロードキャストメッセージを受信し、応答を正常に送信します。

クライアント側では、ファイアウォールログは、サーバーの応答がマシンに到着し、それが正しいポート(クライアントの検出ソケット)にアドレス指定されていることを示しています。ただし、メッセージがクライアントアプリに届くことはありません。ブロッキングモードと非ブロッキングモードでrecv()を実行しようとしましたが、使用可能なデータがありません。ioctlsocket()は、パケットがマシンにデータを取得したことを知っていても、常に利用可能なデータがないことを示します。

サーバーは、ブロードキャストされたデータに対してrecv()を実行することに成功します。ただし、クライアントは、検出ソケットにアドレス指定されたサーバーの応答のrecv()の実行に失敗します。

質問は非常にあいまいです。このシナリオでは、どのような落とし穴に注意する必要がありますか?recv()が実際にマシンに到着したパケットを取得できないのはなぜですか?ソケットはUDPであるため、接続されていないという事実は関係ありません。またはそれは?

よろしくお願いします。

4

2 に答える 2

0

クライアントは、任意のポートにバインドされたクライアントUDPソケットの「名前」を含むメッセージをブロードキャストします。これをクライアントの検出ソケットと呼びます。

メッセージには何も含める必要はありません。'検出ソケット'から空のメッセージをブロードキャストするだけです。recvfrom()サーバーにそれがどこから来たのかを知らせ、直接応答することができます。

サーバーはブロードキャストをrecv()し、次にクライアント検出ソケットにそのリスニングソケットの「名前」をsendto()します。

十分に公平ですが、実際にはサーバーは5秒ごとなどに独自のTCPリスニングポートをブロードキャストできます。

クライアント側では、ファイアウォールログは、サーバーの応答がマシンに到着し、それが正しいポート(クライアントの検出ソケット)にアドレス指定されていることを示しています。しかし、メッセージがクライアントアプリに届くことはありません

ホストに到達した場合は、アプリケーションに到達する必要があります。どういうわけか、ポートが混同されている必要があります。上記のように簡略化して、再試行してください。

于 2013-02-22T02:09:18.750 に答える
0

Windows ファイアウォールが他のファイアウォールのほかにアクティブで、静かにパケットをドロップしていたのです。無効にすると問題が解決しました。

しかし、サーバーがブロードキャストを通じて送信されたパケットを受信できるようにするため、それがどのように機能するかはまだわかりません。そして、私が機知に富み、サーバーがブロードキャストを介して応答するように設定したとき、それらのパケットはドロップされました。

怒濤の2日間。誰かが私の経験から利益を得ることを願っています。

于 2013-02-22T16:19:56.740 に答える