1

スタックオーバーフローユーザー!

p2p を処理する必要があるアプリがあり、それが UDP ホール パンチングに到達する方法です。しかし、私は実装に問題がありました。ヒントを教えてください。

完璧に機能し、クライアントを相互に紹介するサーバーを持っていますが、クライアントは、おそらくソケットを扱っている私の小さな経験のために接続できません。したがって、クライアントアルゴリズムは次のとおりです。

  1. UDP ソケットを作成します ( socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); )
  2. sendto関数を介してサーバーにメッセージを送信する
  3. recvfromロッカー関数を使用して、サーバーから応答を取得します

これらの 3 つの手順の後、ピア エンドポイントを取得します。次に、次の 2 つの方法でクライアントを接続しようとしました。

Way1 :

  1. 同じソケットを使用してsendto関数経由でピアにデータを送信しますが、別のsockaddrを渡します
  2. recvfromロッカー関数をリッスンします (その時点でWSAECONNRESETエラーが発生します)

Way2 :

  1. 新しいソケットを作成する
  2. バインドする
  3. ピアにデータを送信するために使用します
  4. 聞く

このように、1 つのクライアントがバインドに失敗し、別のクライアントがエラーWSAEADDRINUSEおよびWSAECONNRESETでリッスンに失敗します。私は明らかに何か間違ったことをしています。あなたの助けをいただければ幸いです。前もって感謝します。

PS Wanna は、UDP ホール パンチングに関する優れた記事を共有して、この手法に慣れていない人を支援します: http://www.brynosaurus.com/pub/net/p2pnat/

4

1 に答える 1

2

のドキュメントを読むと、次のrecvfrom()ようになります。

WSAECONNRESET

仮想回線は、リモート側がハードクローズまたはアボートクローズを実行することによってリセットされました。アプリケーションはソケットを閉じる必要があります。使用できなくなりました。UDPデータグラムソケットでは、このエラーは、前の送信操作がICMPポート到達不能メッセージをもたらしたことを示します

これは、への呼び出しsendto()が失敗していることを意味します。これは、一方または両方のクライアントがルーターの背後にある場合に意味があります。説明(およびコードの欠如)に基づいて、クライアント間パケットが通過できるようにルーターを開くための穴あけを実際に実行しているわけではありません。サーバーにメッセージを送信しただけです。これにより、クライアントからサーバーへのパケットとサーバーからクライアントへのパケットが通過できるようになります。リンク先の記事で詳しく説明されているように、両端で穴あけを実行するには、各クライアントとサーバー間でさらにいくつかのパケット交換が必要です。記事に書かれていることを実際にやっていますか?

于 2012-12-12T22:26:43.747 に答える