- ベストアンサー
サーバプロセスとクライアントプロセスの通信とは?
- サーバプロセスとクライアントプロセスの通信は、TCPコネクションを介して行われます。
- 通信処理では、クライアント側の各プロセスとサーバ側の対応するプロセス間で通信が行われます。
- 通信にはIPアドレスとポート番号を組み合わせたソケットが使用され、クライアント側では各プロセスごとにソケットが作成されます。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>1つのポートに対して通信が集中すると、輻輳が起きて遅延が発生することはありますか? 理論上はありません。 「OSの不具合(ソフトウェア障害)」や「サーバプログラムの不具合」で発生する可能性はあります。 >子プロセス群に対して、個別にポート番号を割り当てる場合、何らかのメリットはありますか? 先に回答した #原則1.TCP/IP上の区別はTCP/IPスタックが行う仕事 #原則2.プロセス側では自身の処理方式ができるだけ単純になる #(=プログラミングが簡単になる)ことだけを考える。 # #に従って、「子プロセスがそれぞれ異なるポートを用いる」方が #単純になる場合、積極的に異なるポートが利用されています。 に該当する場合はメリットがありますね。 具体的なメリットは、回答で挙げている実例を参照してください。 >実際に手を動かしてみた方が理解しやすいので、 >お勧めのネットワークプログラミング書がありましたら教えてください。 ある程度のプログラムスキルがある場合、 著名なOSS(オープンソースソフトウェア)のソースコードを読んで、 内容理解できるようになるのが一番です。 「IT業界が過去数十年の経験で蓄えた、ベストプラクティスの要素を備えている」 というのがその理由。 多くの書籍では「動くけれど、最適ではない」コードしか載せていない点も OSSのソースコード読解を薦める理由です。 プログラムスキルに不安がある場合、 C言語でよければ、下記URLの 「第 05 回 2003/11/10 プログラミングの基礎知識(1)」以降が ネットワークプログラミングの話です。 http://www.soi.wide.ad.jp/class/20030030/?20030030 # 書籍でなくて申し訳ない。 # 書籍は心当りがありません… プログラミング経験がない場合、 「プログラミング環境を整える(ソフトウェアインストールなど)」 「プログラミング環境の使い方を覚える」 といったあたりが一番の難関なので、プログラム言語の質問カテゴリで 新たに質問することをお勧めします。 # 上記のURLもプログラミング環境が整っていることが前提になっています。
その他の回答 (5)
- onosuke
- ベストアンサー率67% (310/456)
>プロセスの作りによっては、子プロセスがそれぞれ異なるポートを用いて、 >クライアントと通信を行うことは可能でしょうか。 次に、上記の仕組みを導入している例について 原則1.TCP/IP上の区別はTCP/IPスタックが行う仕事 原則2.プロセス側では自身の処理方式ができるだけ単純になる(=プログラミングが簡単になる)ことだけを考える。 に従って、「子プロセスがそれぞれ異なるポートを用いる」方が単純になる場合、積極的に異なるポートが利用されています。 例1.ネットワーク管理サーバ(以下、NMS) 理由: 2つの役割が存在するから NMSでは、 管理コンソール-(独自プロトコル)-NMS:管理コンソール機能 ネットワーク機器-(SNMPプロトコル)-NMS:SNMPクライアント機能 という2つの役割(と2つの通信プロトコル)が存在します。 このような2つの役割をそれぞれ子プロセスとして、別のポート番号を用いることが良く行われます。 例2.IP電話(Skypeなども) 理由: 制御とデータの通信パスを分離するため IP電話では、音声データが継続して双方向に流れています。 この途切れない音声データ中に制御命令を割り込ませるのは、面倒な話が多いため、制御処理と音声データ処理とで別のポート番号を用いることが良く行われます。 制御は、サーバ-クライアント間の通信パス。 音声データは、クライアント-クライアント間の通信パス。 など「音声データはサーバを経由させない」といった応用も可能になります。 番外編.FTP 理由: プロトコルの設計が古い(本来は異なるポートを用いるべきではなかった) FTPでは、例2と同様、制御とデータの通信パスを分離していますが、実は分離する必要がありません。もっとも、FTPプロトコル作成当時はTCP/IPが最先端技術だったので、しょうがない話もあります。 失敗事例の反面教師としましょう。
お礼
ご回答ありがとうございました。 プログラミングを通して学ぶのが、着実なアプローチ方法ですね。 『回答日時:2010/11/15 06:24』の補足に記載しておりますが、お勧めのネットワークプログラミングの書籍はありますか?
- onosuke
- ベストアンサー率67% (310/456)
申し訳ない。 記述誤りがありました。 >【サーバプロセスが起動する時の処理フロー】 >1.「サーバプロセス」が「TCP/IPスタック:サーバOS」にソケットの作成を依頼する。 誤: 依頼内容は、"送信元(指定なし)"、"LISTEN(待受)"。 正: 依頼内容は、"送信元 0.0.0.0:22"、"LISTEN(待受)"。 IPアドレス 0.0.0.0は、アドレス指定なしを表します。 >プロセスの作りによっては、子プロセスがそれぞれ異なるポートを用いて、 >クライアントと通信を行うことは可能でしょうか。 可能ですが、プロセスの立場で考えると クライアントを区別するにはソケット番号が異なっていれば十分 なので、そのような処理が煩雑/複雑になる手段は用いないのが"普通"です。 "普通"というのは、原則論で表現すると、以下のような考え方です。 原則1.TCP/IP上の区別はTCP/IPスタックが行う仕事 原則2.プロセス側では自身の処理方式ができるだけ単純になる(=プログラミングが簡単になる)ことだけを考える。 実際に >異なるポートを用いて、 を実現するには、 >1.「サーバプロセス」が「TCP/IPスタック:サーバOS」にソケットの作成を依頼する。 >2.「TCP/IPスタック:サーバOS」は、「サーバプロセス」に"番号札(ソケット番号A▲)"を渡す。 を複数回繰り返す必要があります。 具体的には、 依頼内容1、"送信元 0.0.0.0:21"、"LISTEN(待受)"。→ソケット番号A1を渡される 依頼内容2、"送信元 0.0.0.0:22"、"LISTEN(待受)"。→ソケット番号A2を渡される 依頼内容3、"送信元 0.0.0.0:23"、"LISTEN(待受)"。→ソケット番号A3を渡される などと繰り返す必要があります。 上記原則論で考えると、1回で実現できることを複数回繰り返すのは、 煩雑で無駄であり、普通は行いません。 # なお、質問内容を避ける理由としては、 # 65536個しかない、ポート番号という資源の無駄使いだ! # という考え方もありますね。
補足
ご回答ありがとうございました。 1つのポートに対して通信が集中すると、輻輳が起きて遅延が発生することはありますか? 子プロセス群に対して、個別にポート番号を割り当てる場合、何らかのメリットはありますか? 実際に手を動かしてみた方が理解しやすいので、お勧めのネットワークプログラミング書がありましたら教えてください。
- onosuke
- ベストアンサー率67% (310/456)
TCP/IPの通信制御をOS(のTCP/IPスタック)が担っている認識は持っていますか? ソケットというのは、プロセスとTCP/IPスタックの間を接続するソケットAPI上の概念です。 サーバプロセスも、クライアントプロセスも通信を行う際は、ソケット番号しか認識していません。 以下、簡単に「接続模式図」「サーバプロセス起動時の処理」「クライアントがサーバに接続する時の処理」をまとめました。一読してみてください。 【「サーバプロセス」と「クライアントプロセス」間の接続模式図】 サーバプロセス | (ソケットAPI:サーバOS) | TCP/IPスタック:サーバOS | (TCP/IPネットワーク:サーバ-クライアント間) | TCP/IPスタック:クライアントOS | (ソケットAPI:クライアントOS) | クライアントプロセス 【サーバプロセスが起動する時の処理フロー】 1.「サーバプロセス」が「TCP/IPスタック:サーバOS」にソケットの作成を依頼する。 依頼内容は、"送信元(指定なし)"、"LISTEN(待受)"。 2.「TCP/IPスタック:サーバOS」は、「サーバプロセス」に"番号札(ソケット番号A1)"を渡す。 3.「TCP/IPスタック:サーバOS」が以下のnetstat行に対応するTCP/IPポートを待受オープン(LISTEN)する。 tcp 0 0 :::22 :::* LISTEN 4.「サーバプロセス」は、定期的に"番号札(ソケット番号A1)"宛の通信が到着しないかを確認する。 【クライアントがサーバに接続する時の処理フロー】 1.「クライアントプロセス」が「TCP/IPスタック:クライアントOS」にソケットの作成を依頼する。 依頼内容は、"送信元(指定なし)"、"宛先192.168.0.4:22"。 2.「TCP/IPスタック:クライアントOS」は、「クライアントプロセス」に"番号札(ソケット番号B1)"を渡す。 3.「TCP/IPスタック:クライアントOS」と「TCP/IPスタック:サーバOS」との間で以下のnetstat行に対応するTCP/IP接続が確立(ESTABLISHED)される。 tcp 0 52 ::ffff:192.168.0.4:22 ::ffff:192.168.0.3:1431 ESTABLISHED 4.「TCP/IPスタック:サーバOS」が上記TCP/IP接続に対応する新しい"番号札(ソケット番号A2)"を作成する。 5.「サーバプロセス」が、"番号札(ソケット番号A1)"宛の通信到着に気づく。 6.「サーバプロセス」が「TCP/IPスタック:サーバOS」から新しい"番号札(ソケット番号A2)"をもらう。 7.「サーバプロセス」はソケット番号A2、「クライアントプロセス」はソケット番号B1、を利用して互いにデータ送受信を行う。 さて、以上を踏まえた上で… >Server側の親プロセスは窓口のような役割を担っており、 >実際に処理を行うのは子プロセスであるということですね。 このようなことを行う場合もあります(sshdが該当)が、 親プロセスがそのまま処理しても問題ありません。 本質は、新しいソケット番号A2が発行されることです。 ソケット番号A2は、子プロセスでも扱っても良いですし、親プロセスがそのまま取り扱っても良いです。逆に待受用のソケット番号A1と新しいソケット番号A2は番号が違うので、親/子プロセスで分担作業ができるとも言えます。 >自宅のLinuxサーバにsshで2セッション分ログインしている状態で >「netstat」コマンドを実行すると、2つのClient側プロセスが22番ポートに >対してコネクションを張っているように見受けられますが、いかがでしょうか。 2つ目のClient側プロセスが22番ポートに接続したときに、さらに新しいソケット番号A3が生成された状態ですね。
補足
非常に分かりやすいご説明ありがとうございました。 クライアントが接続してくるにつれて、A2、A3、A4・・・と新しいソケットを生成していきますが、SSHの場合、、親プロセスと子プロセスは同じポート「22」を使用しております。 プロセスの作りによっては、子プロセスがそれぞれ異なるポートを用いて、クライアントと通信を行うことは可能でしょうか。
- nico-papa
- ベストアンサー率25% (1/4)
Server側23番ポート(Well Known Port)でClient側からの接続を待ちます。 Client側が接続に来ると、子プロセスを起こして、この子プロとClientの間でセッションを確立します。 子プロのポートはWell Known Ports以外の番号が割り当てられます。 後はServer側子プロセス(含ソケット)とClient側プロセスとの間の通信になるので、特にどのポートか解らなくなる事はないです。
補足
ご回答ありがとうございます。 Server側の親プロセスは窓口のような役割を担っており、実際に処理を行うのは子プロセスであるということですね。それであればソケットの話も納得できます。 追加で確認させて頂きたい点がございます。 自宅のLinuxサーバにsshで2セッション分ログインしている状態で「netstat」コマンドを実行すると、2つのClient側プロセスが22番ポートに対してコネクションを張っているように見受けられますが、いかがでしょうか。 また、「:::22」はsshdがリッスン(監視)しているポートを表しているものでしょうか。 よろしくお願いいたします。 <netstat結果> [hide@cd1ha001 ~]$ netstat -an | grep :22 tcp 0 0 :::22 :::* LISTEN tcp 0 52 ::ffff:192.168.0.4:22 ::ffff:192.168.0.3:1431 ESTABLISHED tcp 0 0 ::ffff:192.168.0.4:22 ::ffff:192.168.0.3:1430 ESTABLISHED
- SaKaKashi
- ベストアンサー率24% (755/3136)
クライアントから接続をするときに接続毎にポート番号が割り当てられます。 なのでクライアントのプロセスはプロセス毎に異なるポート番号を持ちます。 サーバ側は、クライアントからの接続要求を受け付けるときにポート番号を覚えているので、 クライアントへの応答通信はそのポート宛に送ります。
補足
ご回答ありがとうございます。 クライアント側より、サーバ側の挙動について確認したいと考えております。 自宅のLinuxサーバにsshで2セッション分ログインしている状態で「netstat」コマンドを実行すると、2つのClient側プロセスが22番ポートに対してコネクションを張っているように見受けられますが、いかがでしょうか。 また、「:::22」はsshdがリッスン(監視)しているポートを表しているものでしょうか。 よろしくお願いいたします。 <netstat結果> [hide@cd1ha001 ~]$ netstat -an | grep :22 tcp 0 0 :::22 :::* LISTEN tcp 0 52 ::ffff:192.168.0.4:22 ::ffff:192.168.0.3:1431 ESTABLISHED tcp 0 0 ::ffff:192.168.0.4:22 ::ffff:192.168.0.3:1430 ESTABLISHED
お礼
ご回答ありがとうございます。 C言語プログラミングは大学時代にかじったことがあるので、WEBページを参考に勉強してみたいと思います。 長々とお付き合いいただき、誠にありがとうございました。