• ベストアンサー

UDP通信する時に、相手にどうやって自分のポート番号を教える?

UDP通信する時に、相手(送信側)にどうやって自分(受信側)のポート番号を教えるのでしょうか? 例えば、下記のページのサンプルだと、受信側は5555で待ち受けていますが、この場合は送信側はあらかじめ受信側が5555で待ち受けていると知っています。送信側が知らない場合に、どうやって受信側のポート番号を知らせればよいのでしょうか? http://www.hellohiro.com/datagram.htm

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

#1です。 > 受信側は > DatagramSocket > を引数なしでインスタンス化して、receiveメソッドを動かせば、そこに返ってくる、ということなのでしょうか? 「返ってくる」というのはレスポンスのことでしょうか。その前提で話をします。 最初の回答のA→B(リクエスト)とB→A(レスポンス)のうち,Aがこの質問のとおりに動作するには,Bが以下のような動作を行う必要があります。逆にBが以下のような動作をするならAの動作はご質問のとおりです。 1)Aは引数なし,Bは固定のポートを指定してインスタンス化。 2)Aは送信するリクエストパケット(DatagramPacket)を作り,これにBのIPアドレスとポートをセットして送信。 3)BのIPアドレス・ポートにAからのパケット到着。Bはこれをreceiveメソッドで受け取る。 4)BはAからのパケットに含まれるAのIPアドレスとポート番号を取得する(DatagramPacketのgetSocketAddressメソッドで多分取得可)。 5)Bはレスポンスを作成し,取得したAのIPアドレスとポートをレスポンスパケット(DatagramPacket)にセットしてこれを送信。 6)AのIPアドレス・ポートにBからのパケット到着。Aはこれをreceiveメソッドで受け取る。 UDPでは,リクエストを送って相手がそれを受け取れば,UDP通信はそれでおわりです。リクエストに対してレスポンスを返す場合,送信側と受信側が入れ替わって新規のUDP通信を始めることになります。

netw2009
質問者

お礼

皆さん、回答ありがとうございます。 自分の中でイメージした感じで、簡単なコードを書いてみたのですが、うまく動きません。ただ、質問が変わってしまうので、下記のページに質問させていただきました。 もしよければ、よろしくお願いします。 http://oshiete1.goo.ne.jp/qa4937796.html

その他の回答 (3)

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.3

> パケットが自分に返ってくる時の自分のポート番号をどう相手に知らせるのか 知らせるまでもなく、TCP/IPレベルで、受信した時点で相手のIPアドレスやポート番号は既知のものです。 Java であれば、 > socket.receive(packet); で受信した時の packet に、その情報が入っていて、 getAddress や getPort で取得できます。 http://java.sun.com/javame/reference/apis/jsr218/ja/java/net/DatagramPacket.html#getPort() ・待ち受ける自分自身のポート番号情報は socket が保持している ・通信相手(こちから送る相手先/こちらが受けとった送信元)のポート番号情報などは packet が保持している ので、 サーバ側では、この受信に使った packet をそのまま使って、setData してから socket.send(packet)してやれば、 通信相手のIPアドレスやポート番号を意識しなくても、 そのまま送信者に返信を送ることができます。 クライアント側では、 ・ポートを指定していないので、socketが使用するポート番号は適当に割り振られる ・socket.send 時には、そのポート番号を送信元としてデータを送りつける ・socket.receive 時には、そのポート番号宛のデータを受け取る ことになるので、 送信に使った socket を使って、そのまま socket.receive(packet)すれば、サーバ側が送り返したデータはそのまま受信できます。

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.2

UDPにかぎらず、TCPでも同じことですが、 クライアント(一番最初に送信を行う)側は、 サーバ(一番最初に受信を行う)側のポート番号を、 別途何らかの手段であらかじめ知っておく必要があります。 その方法としては、 ・ポート番号を決めうちにする   たとえば、http はTCPの 80 であるとか、DNS はUDPの53番を使うと、あらかじめ決めておく。質問者さんの挙げてるサンプルもこの方法ですね。 ・別の通信で、ポート番号などの情報交換を行う。   ftp(TCP)では、コントロールとデータの2つのコネクションを張りますが、データコネクションのポート番号はコントロールコネクションで通知します。   WWWで、http://excample.com:8080/foo/bar/ などとポート番号込みでURLを指定するのも、この方法の一種でしょう。 などがあります。

netw2009
質問者

お礼

回答ありがとうございます。 すみません、私の書き方が悪かったのですが、私が知りたかったのは自分が相手のウェルノウンポートに送った後に、パケットが自分に返ってくる時の自分のポート番号をどう相手に知らせるのか、ということでした。

回答No.1

2点間,たとえばAとBの間でUDP通信を行う場合,最初のA→B(リクエスト)を行うポート番号は教えようがありません。Bはあらかじめ決めた固定のポート番号にバインドしてAはそのポート番号にリクエストを投げる必要があります。 しかし,B→A(レスポンス)については,A→Bで送られたリクエストパケットの中に送信元ポート番号(Aのポート番号)が含まれているので,その送信元ポートにレスポンスを投げ返すのは可能かと思います。 詳しくはUDPパケットの仕様を調べてみてください。

参考URL:
http://www.atmarkit.co.jp/fwin2k/network/baswinlan013/baswinlan013_03.html
netw2009
質問者

お礼

回答ありがとうございます。 私の質問文が不十分だったのですが、私が知りたかったのはB→Aのレスポンスする時のBが、Aのポート番号の知り方でした。 ということは、下記のプログラムでいうと、受信側は DatagramSocket を引数なしでインスタンス化して、receiveメソッドを動かせば、そこに返ってくる、ということなのでしょうか? http://www.hellohiro.com/datagram.htm

関連するQ&A