closeの際のreadについて教えてください (「なぜつながるのか」 p.86)

お世話になります。
「ネットワークはなぜつながるのか」を読みまして、不明な点がありましたので、質問をお願いいたします。

86ページ、7行目、コネクションの切断の説明です
「ブラウザがreadで受信動作を依頼したときに、・・・」
とありますが、ウェブのファイルを受信し終えた後、ブラウザは、何故更ににreadを行うのでしょうか?
サーバからの切断の指示が来ることを前提として、ファイル受信用のreadと、切断指示受信用のreadの2回のread依頼を出すと言う理解でいいでしょうか?

お教えください。
よろしくお願いいたします。

名前: 
匿名希望
日時: 
13/07/07 22:50

コメント

匿名希望さん,こんばんわ。
拙書お読みいただき,ありがとうございます。

> ウェブのファイルを受信し終えた後、ブラウザは、何故更にreadを...

readとかwriteという動作は通信だけでなく,
ファイルを読み書きする際にも使う一般的な動作です。
それなのに,readやwriteを実行するプログラムの基本的な考え方が
あの本には書いてないですね。(^^;
プログラミングの解説本じゃないので,その辺はお許しください。

なので,read動作を実行するプログラムの基本から書きますね。

まず,基本的な前提ですけど,
1回のreadでデータを全部読み込むことは,ほとんどありません。
そして,データがどのくらいの長さなのか,事前にはわからない,
と仮定することが多いです。
大きなデータを一度に読み込もうとすると,
メモリが大量に必要になるっていう事情が背景にあるからなのですが。

そこで,1回に1バイト分ずつ,あるいは1行分ずつという感じで,
細切れにしてデータをreadします。
そして,read動作を繰り返すと,そのうちにデータの最後尾に達し,
そこで実行したreadの結果として,
OSから「データは終わったよ」という意味の情報が返ってきます。
これでデータの終わりを知るわけです。

データの末尾に「これで終わり」っていう意味の情報入れておいて,
それで終わりを知るっていう方法もありますけど,
画像データなどのバイナリデータを扱うときは,
データの中に「これで終わり」と同じものが入っていたりすると,
面倒なことになりますから,
その方法は今は一般的ではありません。

そうなると,データが終わったよという情報,
(通信の場合は,送信動作が終わって切断したよ,という情報)
が返ってくるまではデータが終わったどうかわからない
っていうことになります。

データの受信が終わったことが分かれば,
もうreadを実行する必要はありませんが,
終わったかどうかが分からないので,
終わりに達するまでreadを繰り返し実行する,
っていうことですね。

こんな説明でわかります?

戸根勤 さま

ご回答有難うございます.
1回のreadの呼び出しで,ファイルの受信だけでなく,接続の切断までカバーしていることが分かりました.

HTTP1.1の場合は,htmlファイルを受信後も,接続を切らず,続けて画像ファイルの要求を行うとの説明でしたので,下のようなプログラムになるかと思います.
---------------
socket
connect

write(htmlファイルの要求)
read(htmlファイルの受信) (※)

(htmlファイルの解析)

write(画像ファイル1の要求)
write(画像ファイル2の要求)
write(画像ファイル3の要求)
read(画像ファイル1~3の受信)

close
---------------

この場合,htmlファイルのread(※)は,何か別の情報で,制御がアプリケーションに戻るのでしょうか?
ご著書記述外の質問で恐縮ですが,お時間あるときにでもお教えください.

今回は,ありがとうございました.
理解が一つ進みました.

こんばんわ。

仕様上,HTTP1.1は続けて複数のリクエストを送信できますけど,
実際のプログラミングはどうなっているのかしら?
私はプログラマを引退して久しく,その辺の事情に疎くなっているので,
匿名希望さんが書いたプログラムのイメージが正しいのかどうか,
判断しかねます。

というのは,普通に考えると,
リクエスト送信とレスポンスの受信はワンセットで考えるので,

---------------
socket
connect

write(htmlファイルの要求)
read(htmlファイルの受信) (※)

(htmlファイルの解析)

write(画像ファイル1の要求)
read(画像ファイル1受信)
write(画像ファイル2の要求)
read(画像ファイル2の受信)
write(画像ファイル3の要求)
read(画像ファイル3の受信)

close
---------------

っていう感じにすることが多いんじゃないかと思うんですよ。
でも,これじゃ画像を一個ずつ順番に扱うことになるので,
性能面で問題になるかもしれません。
リクエスト送信とレスポンス受信をワンセットにして,
スレッドか何かで併行処理した方が速いですからね。

この点,HTTP1.0ならリクエスト送信とレスポンス受信毎に
コネクションが別々になりますから,
それぞれのコネクションのソケットをスレッドに渡せば
簡単に併行処理できます。
(コネクションが増えるとメモリ消費量も増えますけど)

HTTP1.1で一つのコネクションで複数のリクエストをやり取りする場合に,
性能面を考えると,どういうやり方が良いのかしら?
その辺の事情知っている方いたら,アドバイスいただけると助かります。 > 皆様

> htmlファイルのread(※)は,何か別の情報で,
> 制御がアプリケーションに戻るのでしょうか?

readを実行するときに受信するバイト数を指定して,
そのバイト数のデータを受信したら制御がアプリケーションに戻る,
っていう格好でプログラミングするのが普通でしょう。
だから,1バイトずつreadするようにプログラムを作れば,
すぐにアプリケーションに制御が戻ってきます。

この辺のことは,細かな部分まで言葉で説明するのは難しいので,
言葉の説明より,論より何とかで,
実際にプログラムを作って試してみる方が良く分かります。

戸根勤さま

何度もご回答ありがとうございました.HTTP1.1の場合,read関数は,所定バイト数で受信完了とすると理解いたしました.

また何かありましたら,よろしくお願いいたします.