CDの保有枚数を教えてください

サーバプロセスとクライアントプロセスの通信がどのように行われているのか確認させてください。
現在、以下の認識でいます。


(1)TCPコネクション
 サーバ側ポート番号【23】と、それぞれのクライアント側ポート番号【****】との間に確立する。
 
(2)通信処理
 クライアント側のプロセスAは、サーバ側のプロセスA(子)
 クライアント側のプロセスBは、サーバ側のプロセスB(子)
 クライアント側のプロセスCは、サーバ側のプロセスC(子)
 との間で通信を行う。

※添付の図も参照ください。


認識に相違ないでしょうか。
サーバプロセスとクライアントプロセスの通信を行う際、プロセス間(ポート間?)の通信には、IPアドレスとポート番号を組み合わせたソケットを用いるため、サーバ側ではソケット【192.168.0.1:23】を1個作成し、クライアント側ではソケット【192.168.0.2:****】をプロセス分作成すると考えています。
このとき、クライアントプロセスAはサーバプロセスA(子)と通信を行いますが、サーバ側で作成されているソケットは1つであるため、どの子プロセスに対してデータをせばいいのか判別できないのではないかと考えています。
※クライアントプロセス(A、B、C)はソケット(サーバ側)【192.168.0.1:23】に対して送信されるため。

上記について、何らかの仕組みがあるのでしょうか。
よろしくお願いします。

「サーバプロセスとクライアントプロセスの通」の質問画像

A 回答 (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もプログラミング環境が整っていることが前提になっています。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
C言語プログラミングは大学時代にかじったことがあるので、WEBページを参考に勉強してみたいと思います。
長々とお付き合いいただき、誠にありがとうございました。

お礼日時:2010/11/28 10:06

>プロセスの作りによっては、子プロセスがそれぞれ異なるポートを用いて、


>クライアントと通信を行うことは可能でしょうか。
次に、上記の仕組みを導入している例について

原則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が最先端技術だったので、しょうがない話もあります。
失敗事例の反面教師としましょう。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。
プログラミングを通して学ぶのが、着実なアプローチ方法ですね。
『回答日時:2010/11/15 06:24』の補足に記載しておりますが、お勧めのネットワークプログラミングの書籍はありますか?

お礼日時:2010/11/23 11:49

申し訳ない。


記述誤りがありました。

>【サーバプロセスが起動する時の処理フロー】
>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つのポートに対して通信が集中すると、輻輳が起きて遅延が発生することはありますか?
子プロセス群に対して、個別にポート番号を割り当てる場合、何らかのメリットはありますか?

実際に手を動かしてみた方が理解しやすいので、お勧めのネットワークプログラミング書がありましたら教えてください。

補足日時:2010/11/23 11:40
    • good
    • 0

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」を使用しております。
プロセスの作りによっては、子プロセスがそれぞれ異なるポートを用いて、クライアントと通信を行うことは可能でしょうか。

補足日時:2010/11/13 23:02
    • good
    • 0

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

補足日時:2010/11/11 23:20
    • good
    • 0

クライアントから接続をするときに接続毎にポート番号が割り当てられます。


なのでクライアントのプロセスはプロセス毎に異なるポート番号を持ちます。
サーバ側は、クライアントからの接続要求を受け付けるときにポート番号を覚えているので、
クライアントへの応答通信はそのポート宛に送ります。

この回答への補足

ご回答ありがとうございます。
クライアント側より、サーバ側の挙動について確認したいと考えております。

自宅の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

補足日時:2010/11/11 23:22
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!