connectとacceptプログラムについて

「ネットワークはなぜつながるのか」で説明されているsocketライブラリーのconnectプログラムとacceptプログラムにつき、同書を読んだ範囲では分からない点がありますので、もう少し教えてください。

(1)connectもacceptもコネクション確立に関係するプログラムであり、そのため、UDPでは使われないと理解しました。

(2)「ネットワークはなぜつながるのか」の305頁上段に次のようにありす。
「そして、新しいソケットにクライアント側のIPアドレスとポート番号、接続を受け付けたサーバー側のIPアドレスとポート番号といった制御情報を登録してサーバー・プログラムに通知します。」

この時、サーバー・プログラム経由でacceptに通知が来るということですか。
また、データ送受信用のバッファ確保と「ACK+SYN」信号送出はacceptが指示するのですか。

(3)同書の97頁に次のように書かれています。
「(SYNが1、ACKが1)を確認したら、三つめのパケットを送り返します。
(中略) これで、接続動作は終わりです。Socketのconnectの実行もここで終わりですから、そうしたら、アプリケーションに制御を戻します。」

ここは、「ACK+SYN」の受信を確認したら、通知がconnectに来て、connectがtcpプログラムに「ACK」を返すように指示してから、実行を終えると理解してよいですか。

(4)コネクション確立の最後にサーバーが「ACK」を受けたときもacceptが対応するのですか。この「ACK」を受けたとき、サーバー側はどんな処理をするのですか。

名前: 
平山広行
日時: 
02/12/11 17:32

コメント

平山さん,はじめまして。

細かい部分まで読み込んでいるよう,お見受けしました。
著者として非常に嬉しいです。

>(1)connectもacceptもコネクション確立に関係するプログラムであり、そのため、UDPでは使われないと理解しました。

はい,そうです。

(2)と(4)の質問は,Socketライブラリ,TCP/IPソフト,アプリケーションの関係を
もう一度整理すると理解できると思います。
SocketとTCP/IPソフトは,実体は別々のものですが,
両者は連動して一つのものとして動く,と考えた方がよいでしょう。
つまり,アプリケーションがSocketの関数を呼び出すと,
SocketとTCP/IPソフトが一体となって,接続,データ送信,切断といった
動作を実行すると考えるわけです。
そう考えて,connectとacceptの動作を時系列に並べると次のようになります。

(1)まず,サーバ側でsocket,bind,listenに続いてacceptを呼び出す。
 ここでサーバプログラムの実行が休止し,TCP/IPソフトの内部で,
 クライアントからパケット(SYN=1のパケット)が届くのを待つ状態に入る。
 ここまでが,サーバ側で接続を待つ準備動作。
(2)クライアント側でsocketを実行し,続いてconnectを実行する。
 すると,クライアント側のTCP/IPソフトが動き出し,そこでSYN=1のパケットをサーバに送る。
 サーバのTCP/IPソフトがSYN=1のパケットに応えて,SYN=1,ACK=1のパケットを返す。
 クライアントのTCP/IPソフトがそれに応えて,ACK=1のパケットをサーバに送り返す。
 これが,クライアントとサーバが連携して動く,接続の動作。
(3)サーバ側でacceptからアプリケーションに制御が戻り,acceptの次のステップに進む。
(4)クライアント側もconnectからアプリケーションに制御が戻り,connectの次のステップに進む。(3)と(4)の動作はほぼ同じタイミングで実行する。
(5)これ以後,クライアントとサーバがデータをやり取りする。

『ネットワークはなぜ...』は探検形式なので,
この動作の説明が,42~46ページ近辺,68~70ページ近辺,302~306ページ近辺に
分かれてしまったため,わかりにくかったかもしれません。
その辺を,その部分をもう一度読み直してみるとよいかもしれません。

それで疑問が解消できないようなら,お手数ですが,もう一度質問してください。

ご返事ありがとうございました。私が要領を得ない質問をしたようで恐縮しています。

「socket ライブラリとtcp/ipソフトは一体となって動く」ことは分かりました。その上で、最終的に私が知りたかったことは、connect/acceptと tcp/ipソフトが、ソケットを仲介して、どのように一体となって動くのか、ということでした。そのために、「ネットワークはなぜつながるのか」に明確に書かれている部分を提示し、その部分で、私が勝手に想像した両者の「係わり」を例として挙げ、質問としてみました。その部分での「係わり」具合が分かれば、他の部分での「係わり」も分かるかもしれないと思ったからですが、私の想像が的外れだったために私の意図が伝わらずご迷惑をお掛けしてしました。スミマセン。

ところで、私が何故「係わり」に関心を持ったかと言いますと、サーバにSYN信号を送る時のconnectとtcp/ipソフトの係わりが書かれている(同書43頁)のに、それがサーバ側のtcp/ipソフトに届いた後、既に動いているacceptとどう連係をとるのか、書かれた個所が見付からなかったからです。

前回の質問(2)はサーバ側でSYN=1を受信したときと想定しました。(もしかしたら、「新しいソケット」という記述があるので、最後のACK=1かも知れないと今は思っています。)質問(3)はブラウザがSYN=1、ACK=1を受信したとき、質問(4)はサーバがACK=1を受信したときでした。
いずれも、受信側での「係わり」が分からないことを示しています。

実は、「ネットワークはなぜつながるのか」を読みながら、自分なりに、処理の流れを表形式に書き出しているのですが、信号受信時の処理の流れだけは納得いくように纏められないでいます。何がしかのヒントでも頂ければ幸いです。

>サーバにSYN信号を送る時のconnectとtcp/ipソフトの係わりが書かれている
>(同書43頁)のに、それがサーバ側のtcp/ipソフトに届いた後、
>既に動いているacceptとどう連係をとるのか、書かれた個所が
>見付からなかったからです。

『ネットワークはなぜ...』の中では,
socket,bind,listen,accept,connect,read,writeといった関数は
すべて,Socketライブラリを構成するプログラムであり,
それがTCP/IPソフトと一体となって動くものとして解説してあります。
43ページにconnectとTCP/IPの関係が記述してあるとのことですが,
ここに書いてあることは,アプリケーションプログラムがconnectを呼び出す動作と,
connectの中の動作(つまり,TCP/IPが一体となって動く動作)であって,
connectとTCP/IPソフトの関係ではないんです。
connectとTCP/IPソフトは,やはり,一体のものなんです。
そのつもりで,もう一度読み直してみてください。

それから,サーバ側の動作は [335] で説明したとおりですが,
acceptに着目すると次のようになります。
(1)サーバ側プログラムがacceptを呼び出す
 サーバ側プログラムは,socket,bind,listenと順に呼び出して,
 ソケットの準備を整えたら,その後,acceptを呼び出します。
 すると,呼び出したプログラムの実行は停止し,acceptに制御が移ります。
(2)acceptがSYN=1の到着を待つ
 acceptはSYN=1が到着するまで待ち状態となります。
 つまり,実行を停止し,SYN=1のパケットが届くまで,じっと待つわけです。
(3)acceptがSYN=1に応答
 SYN=1が到着したらその内容を検査し,接続を許可する場合は,
 ACK=1,SYN=1を返す
(4)acceptがACK=1をの到着を待つ
 ACK=1,SYN=1を返したら,相手からACK=1が返ってくるはずなのでそれを待ちます。
(5)acceptがACK=1を受信
 ACK=1を受信したら,接続動作は完了したものとします。
 これでacceptの実行は終わり,制御をサーバ側プログラムに戻します。
(6)サーバ側プログラムの実行再開
 acceptを呼び出したプログラムの実行が再開し,次のステップに進みます。

44~45ページにもう少し詳しい説明がありますから,
そちらも参照してください。

また,Socketライブラリとアプリケーションプログラムの関係は,
OSの機能を呼び出すシステムコールの一種ともいえるので,
アプリケーションとOSの関係も勉強してみるとよいかもしれません。
マルチタスキングでのタスクスイッチングも参考になると思います。