• 締切済み

TCP及びUDP通信について

TCP及びUDP通信について 現在WinSockAPIを用いた通信を行うプログラムを組んでいます。 しかしながらネットワークに関しては初心者で、わからない点がいくつか出てきたので質問させて頂きます。 -------------------------------------------------- 1.TCPで双方向通信を行う場合、サーバ側は指定したポートにbind→listenし、接続を待ち受けます。 クライアント側はサーバのIPを指定し、接続確立後にポートはOSが自動で割り振ると聞きました。 つまり、クライアント側がポートを開放せずに通信が出来るのは、OSなどが自動でポートを割り当て、割り当てたポートに到着したデータを該当アプリケーションに渡すからでしょうか? ポート関連は全てルータが管理しているものだと思っていたのですが、OSがポートを割り当てるという動作がよく理解できません。 -------------------------------------------------- 2.UDPで双方向通信を行う場合、端末A・端末Bともに指定したポートにbindする必要があると聞きました。 つまり、UDPで双方向通信を行う場合、端末A・端末Bの双方でポートを開放する必要があるということでしょうか? -------------------------------------------------- 是非ともご教授ください。

みんなの回答

  • Toshi0230
  • ベストアンサー率51% (836/1635)
回答No.2

アプリケーションの開発はよく知りませんがネットワークの観点から: まず、TCP/UDPともにパケット内に「宛先ポート番号」「送信元ポート番号」の2つが必ず含まれる必要があります。クライント側が最初にパケットを生成するときは、宛先ポート番号にサーバ側のポート番号、送信元ポート番号にはクライアントのOSが割り当てた(またはアプリケーションで指定された)ポート番号が含まれることになります。 サーバ側がクライアントからパケットを受信し、それに応答するとき、応答パケット内の送信元ポート番号にはサーバ側のポート番号、宛先ポート番号にはクライアント側が割り当てたポート番号を設定して送信します。これはTCP/UDPとも基本的には同じです。 TCPの場合、実際の通信を始める前に「セッションの確立」を行います。まぁ、仮想的にサーバ~クライアント間に回線を張る様なものだと思って下さい。この部分は通常OSがやってくれますので、アプリケーションはセッションが確立されたらあとはデータの送受信を行うだけです。なので、 > 割り当てたポートに到着したデータを該当アプリケーションに渡すからでしょうか? という質問者さんの認識は合っているといえます。 > ポート関連は全てルータが管理しているものだと思っていた ルータは本来、ポートなんて見ません。IPアドレスを参照して、IPデータグラム(パケット)を適切な宛先に送信するのがルータの本来の役目です。 ただし、昨今のブロードバンドルータではNAPT = Network Address and Port Translation機能が搭載されており、ここでLAN側のIPアドレスとポート番号を適当な値に変換してしまうので、一部アプリケーションを使用するときに意識されるだけです。 TCP/UDPの通信は、双方のOSが持つIPアドレスとTCP/UDPのポート番号を使用して識別されます。 UDPの場合、「セッションの確立」は行われません。もし似た様なことをやりたい場合は、アプリケーション自体がセッション処理を行う必要があります。 UDPでクライアントがサーバの応答を受信したい場合、一定時間はそのポートでパケットを待ち受ける必要があります。この処理をプログラムでどう実装するかは知りませんが、理屈の上からはそうなります。 > UDPで双方向通信を行う場合、端末A・端末Bの双方でポートを開放する必要がある これはルータのNAPTのことを指していますか? 通信内容にもよりますが、UDPの発信-応答の間隔が短ければ、大抵のNAPTはサーバからの応答を透過します(でないとDNSが検索できない…)。そうでない場合、つまり発信と応答の間隔が長くなる場合はNAPTにて所謂「ポートの開放」を実施する必要があります。 端末にインストールされたファイアウォールを指している場合、サーバ機能を果たす端末側に関してはポートを開放した方が良いでしょう。IP Messengerの様に全ての端末がサーバ機能を持つ場合は、全ての端末でポート解放が必要になります。

  • Wr5
  • ベストアンサー率53% (2173/4061)
回答No.1

>クライアント側がポートを開放せずに通信が出来るのは、OSなどが自動でポートを割り当て、割り当てたポートに到着したデータを該当アプリケーションに渡すからでしょうか? そうなります。 クライアント側の「送信元ポート番号」は一般的にOSに任せるのが普通です。 OS(TCP/IPプロトコルスタック)はその時使用されていないポート番号を無作為に選び使用します。 bindして、送信元ポートを固定することも可能ですが、そうすると別のサーバへの接続が 出来なくなります。(指定した送信元ポートは他の通信の為にbindされている為) WinSockのプログラミングで、たまに「bindに失敗するのですが?」という質問で、送信元ポート番号をbindしている方がいます。 >ポート関連は全てルータが管理しているものだと NAT機能の場合、ルータは「送信先IP/ポート番号」と「送信元IP/ポート番号」を保持していて、 そのうち「送信元IP/ポート番号」を外向けのモノ(WAN側)に書き換えた上でパケットを送信します。 その際、組み合わせと変更した内容を保持し、戻って来たパケットの「送信先IP/ポート番号」を確認、書き換えたものを修正して返します。 この時、ルータに対してパケットを送る場合、送信元ポート番号はOSによって既に設定されていることになります。 「NAT 仕組み」等で検索すると、説明されているページが見つかるでしょう。 UDPに関してはほとんど触ったことありませんので、他の人からの回答に任せます。