2009-04-29 13 views
4

私はUDPテストクライアント/サーバを作成しています。ファイアウォールを介して取得したいのですが。おそらく私がする必要があるのは、双方が正しいIPとサーバーに送信されることだけです。 IPを取得することは問題ではありませんが、クライアントにランダムな空きポートを選択してユーザーに報告するにはどうすればよいですか?私は最終的にはそれをマッチメーカーのサーバーに接続したいと思っていますが、今は簡単なプロトタイプが必要です。ポート番号を覚えておいて、私の友人/テスターが#無料のソケットポートを取得するにはどうすればよいですか? C++

どのように私は、ポート番号を得るのですか? 申し訳ありませんが、長いdesc。私は人々が私に私が何かをしないように言っていることに気付きます。(

答えて

5

(予約ポートの明確な舵取りしてください)別のを試してみてください、これは実際にはかなり不快な問題や不快の問題さえペアです。ファイアウォールの構成によっては、通常、要求が出されたときにIPエンドポイント上の別のエンドポイントからの応答が許可されます。だから友人がrecvfrom()システムコールのようなものを使ってUDPデータグラムを受信すると、addressパラメータは応答するIPエンドポイント情報を受信します。したがって、もう一方の側は同じアドレッシング情報を使用してsendto()で応答できるはずです。以下のような何か:

/* initiator */ 
struct sockaddr_in hisaddr; 
memset(&hisaddr, 0, sizeof(hisaddr)); 
hisaddr.sin_addr.s_addr = htonl(target_ip); 
hisaddr.sin_port = htons(target_port); 
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&hisaddr, sizeof(hisaddr)); 

/* receiver */ 
struct sockaddr_in peeraddr; 
socklen_t peer_sz = sizeof(peeraddr); 
recvfrom(sd, buf_ptr, buf_sz, 0, (struct sockaddr*)&peeraddr, &peer_sz); 
/* build response */ 
sendto(sd, msg_ptr, msg_sz, 0, (struct sockaddr*)&peeraddr, peer_sz); 

反対側のpeeraddrがあなたの外部アドレスまたは、より正確には、ファイアウォールのIPアドレスと、それが使用することを選択したポート番号になります。コードで指定するポート番号は、友人がデータを送信するポートとは完全に異なる場合があります。最終的には、ファイアウォールがまったく別のポートで送受信している可能性があるため、どのポートを使用するかは問題ではありません。これはNetwork Address Translationのすべてです。その障壁を克服するためのヒントについては、RFC3235を読むことをお勧めします。

最良のアプローチ私見さ:クライアントを持つ

  1. OSがゼロポート番号でbind()を呼び出したり、バインドを飛ばしいずれかの方法でポートを選択してみましょう全く
  2. がソケットからアドレス情報を受け取りますレイヤー(例:recvfrom()の第5引数と第6引数)
  3. クライアントは前の手順で取得したエンドポイントに応答を送信します
  4. 前の手順が完了するまでファイアウォールの設定を調整しますrk

もちろん、すべての魔法は最後のステップです。 NATを無効にしたり、ファイアウォールが決してポートを切り替えることができないようにするには、ポート番号を釘付けにしてbindを実行することもできます。どのようなポート番号が予約されているのか、あるいは一般に使用されているのかを知るには、%WINDIR%\system32\drivers\etc\services(またはOSの傾きに応じて/etc/services)を見てください。

0

あなたは開発者としてポートを選択します。ユーザーの入力または - しかし、魔法のファイアウォールは、私が正しくあなたの質問を理解していた場合、私はあなたがプログラム的に(とでも欲しいものを行う方法がありますかわからない...どのポートを使用する

0

をあなたに言うつもりはありませんそれが正しいとは思わない)サーバマシンでは使用されていないポートを見つける必要があると思います(クライアントマシン上の別のポートまたは同じポート、通信が双方向性)、そのポートはファイアウォールを通過できる必要があります。「IPを取得することは問題ではない」と言って以来、ファイアウォール内の特定のコンピュータにポートの一部またはすべてを転送するようにファイアウォールを設定しましたか?そうであれば、あなたが求めるポートはあなたが転送したポートの1つです。そのポートで他のサービスが実行されていない限り、任意のポートを選択できます。 1024より小さいポートは予約されているので、おそらくそれより高い数値を選んでください。 nmapなどの簡単なポートスキャンツールを使用して、どのサービスがどのポート上で実行されていて、別のサービスを選択しているかを確認できます。 nmapは、ソケットの作成時にファイアウォールやさまざまなbindルールに惑わされる可能性があることに注意してください。

0

は、私はあなたが、固定ポートを選ぶのではなく、O/Sによって選択されたランダムなポート番号に頼るほうだと思います。あなたはランダムなポートを使用する場合は

あなたは、ファイアウォールの設定、それぞれ、あなたがプログラムを実行するたびに変更する必要があると思います。

0

あなたはWINSOCKチェックこのリンク使用している場合: http://msdn.microsoft.com/en-us/library/aa280717(VS.60).aspx を基本的には0にポートを設定2つの選択肢があり、システムがあなたに1つを割り当てるか、それが動作しない場合は、ランダムな1ソケットを開こうと選んだみよう高度な技術用語を使用するには

0

データを送信する前にソケットをbind()します。 bind()にポート0を指定すると、OSは未使用のポートを選択します。 getsockname()を使用して、選択したポートwsaを見つけることができます。

関連する問題