- PR -

readがサーバ側のソケットが閉じられるまで制御を返してくれません。

投稿者投稿内容
ナリエモン
会議室デビュー日: 2004/03/25
投稿数: 7
投稿日時: 2004-09-24 18:49
RedHatLinux7.2 kernel 2.4.22でTCPクライアントをC++で作成しています。
char chRead;
std::string Buffer;
while(1)
{
if(read(sock,&chRead,1))
Buffer += chRead;
else break;
}
readがサーバ側のソケットが閉じられるまで制御を返してくれません。
サーバ側はデータを転送しているのはイーサネットアナライザPacMonProで確認しています。
サーバ側がクライアントソケットを閉じれば問題ないのですが、
サーバ側がクライアントソケットを閉じるのは何らかのエラーが発生した場合ですよね?
通常はクライアント側がソケットを閉じて終了だと思っています。
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2004-09-24 19:47
引用:

ナリエモンさんの書き込み (2004-09-24 18:49) より:
RedHatLinux7.2 kernel 2.4.22でTCPクライアントをC++で作成しています。
char chRead;
std::string Buffer;
while(1)
{
if(read(sock,&chRead,1))
Buffer += chRead;
else break;
}
readがサーバ側のソケットが閉じられるまで制御を返してくれません。


そうなるでしょうね。
このコードだとループを抜けるのは read() が 0 を返したときで、
read() が 0 を返すのはソケットから EOF を読み出したときで、
ソケットに EOF があるのは相手が接続を切断した場合ですから。

[ メッセージ編集済み 編集者: ぽんす 編集日時 2004-09-24 19:48 ]
ナリエモン
会議室デビュー日: 2004/03/25
投稿数: 7
投稿日時: 2004-09-24 21:55
レスありがとうございます。

ということはサーバ側がクライアントソケットを閉じるのが普通なのでしょうか?
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2004-09-24 23:34
クライアントが read() しつづける永久ループに入る、なんてことは
ふつうはやりません。「改行コードが来るまで読む」とか、使用する
プロトコルに応じて都合の良いやりかたで読みます。
ナリエモン
会議室デビュー日: 2004/03/25
投稿数: 7
投稿日時: 2004-09-25 02:27
引用:

ぽんすさんの書き込み (2004-09-24 23:34) より:
クライアントが read() しつづける永久ループに入る、なんてことは
ふつうはやりません。「改行コードが来るまで読む」とか、使用する
プロトコルに応じて都合の良いやりかたで読みます。


そうですか?
http://x68000.startshop.co.jp/~68user/net/c-http-1.html
を参照して作ったのですが・・・
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2004-09-25 10:18
HTTP 限定の話ですか?
引用:

ナリエモンさんの書き込み (2004-09-25 02:27) より:
http://x68000.startshop.co.jp/~68user/net/c-http-1.html
を参照して作ったのですが・・・


> 103: sprintf(send_buf, "GET %s HTTP/1.0\r\n", path);
に注意しましょう。HTTP 1.0 は、データ転送完了後にサーバが
自動的に切断するとゆー、TCP/IP ではあんまり普通じゃないやり方を
するプロトコルです。
# HTTP 1.1 では切断しないのがデフォルト

あとおまけ。
read() がエラーを返した場合のことを意識しておいたほうが
よいでしょー。
# いちばん問題なのは割り込まれた場合の処理だけど...
# それはとりあえずは考えなくてもいいかな。

[ メッセージ編集済み 編集者: ぽんす 編集日時 2004-09-25 10:31 ]
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2004-09-25 10:32
引用:

そうですか?
http://x68000.startshop.co.jp/~68user/net/c-http-1.html
を参照して作ったのですが・・・


まぁネットで手に入る情報は(書籍や学校でもそうか…)玉石混合だからね。
BlockingModeで処理するなら、最低でもタイムアウトを設定するか、KeepAliveぐらいは付けないと。じゃないと通信が途中で途絶したとき、デッドロックしちゃうよ。
ナリエモン
会議室デビュー日: 2004/03/25
投稿数: 7
投稿日時: 2004-09-25 15:29
引用:

ぽんすさんの書き込み (2004-09-25 10:18) より:
HTTP 限定の話ですか?
引用:

ナリエモンさんの書き込み (2004-09-25 02:27) より:
http://x68000.startshop.co.jp/~68user/net/c-http-1.html
を参照して作ったのですが・・・


> 103: sprintf(send_buf, "GET %s HTTP/1.0rn", path);
に注意しましょう。HTTP 1.0 は、データ転送完了後にサーバが
自動的に切断するとゆー、TCP/IP ではあんまり普通じゃないやり方を
するプロトコルです。
# HTTP 1.1 では切断しないのがデフォルト

あとおまけ。
read() がエラーを返した場合のことを意識しておいたほうが
よいでしょー。
# いちばん問題なのは割り込まれた場合の処理だけど...
# それはとりあえずは考えなくてもいいかな。

[ メッセージ編集済み 編集者: ぽんす 編集日時 2004-09-25 10:31 ]



お世話になっています。
> 103: sprintf(send_buf, "GET %s HTTP/1.0rn", path);
で1.1を要求するとサーバー側がソケットを閉じずにread待ちなる
かな?と思いましたが結果は同じでした。
う〜ん、なにが違うのだろ?
なにかいいサーバのソースご存知ないですか?
apacheなど余りにもソースが巨大でどこから追えばいいか分からず
挫折しました(汗

スキルアップ/キャリアアップ(JOB@IT)