68user's page 掲示板

Prev< No. 580〜582> Next  [最新発言に戻る] [過去ログ一覧]
No. 580 # るん 1999/12/03 (金) 17:38
返事ありがとうございます。

> - どういうリクエストを送ったのか
> - 環境 (Windows など)
> - 何を実行したのか (telnet でやったとか perl で書いたとか)
> - どの URL を試しても同じ結果になるのか
> - 実際のコードは (perl と C 以外わかりませんけど)

環境:UNIX
言語:C言語でproxyサーバにはsocket通信でリクエストを送っています。
具体的には以下の内容をsendで送っています。
GET http://www.yahoo.co.jp/ HTTP/1.1
Host:www.yahoo.co.jp
(空行)

※proxyサーバが社内のマシンしかアクセスできない設定になっているので、
    実際にはwww.yahoo.co.jpの部分は社内のhost名を指定しています。

>> ヘッダしか取出せません。

この後、もうちょっと調べてみると、
一度目のrecvでレスポンスヘッダが送られてきて、
二度目のrecvでエンティティボディが取出されることがわかりました。
NetscapeProxyServerの仕様なのでしょうか。

あと、レスポンスヘッダ文字列の大文字小文字ですが、
本などでは"-"の後の文字は大文字なのですが、
上記の環境で行うと小文字になります。
(例)「Last-Modified」→「Last-modified」など。。。
これもNetscape Proxy Serverの仕様なのでしょうか。

御存知のことがあれば教えてください。

No. 581 # 68user 1999/12/03 (金) 18:15
> 一度目のrecvでレスポンスヘッダが送られてきて、
> 二度目のrecvでエンティティボディが取出されることがわかりました。
十分な量のバッファを用意して、十分なサイズを指定したからといって、
一度の recv で全てのデータを取り出せるという保証はありません。
これは read でも同じです。
    http://X68000.startshop.co.jp/~68user/net/c-open.html
の最後には
> もし指定したファイルの長さが 600 バイトなら、
>  1回目のループ: read_size == 256
>  2回目のループ: read_size == 256
>  3回目のループ: read_size == 88
>  4回目のループ: read_size == 0
と書きましたが、これは相手がファイルシステムだからであって、
ソケット経由だと、
    char buf[1000];
    read(socket,buf,sizeof(buf));
としても、
    1回目のread: read_size == 10
    2回目のread: read_size == 20
    3回目のread: read_size == 1
    4回目のread: read_size == 0
などとなる可能性があります (この例ではデータ量は31バイト)。

要は IP パケットが細切れに送られてきたとき、read(recv) すると
要求されたサイズのデータが届くまで待つのではなく、そのときまでに
受け取っているデータを返すわけです。例えば echo サーバで、
    $|=1;
    print(SOCKET,"a"); sleep(5);
    print(SOCKET,"b"); sleep(5);
    print(SOCKET,"c"); sleep(5);
とすると、細切れなデータが送られるわけです。

> (例)「Last-Modified」→「Last-modified」など。。。
Netscape Proxy Server がわざわざ変換しているのか、
WWW サーバがそういうヘッダを返すのかはわかりませんが、
規格上は大文字小文字は区別されません (RFC のどこかに書いてあるはず)。

Last-Modified/Last-modefied/LaSt-MODIfied は同じように
扱わないといけません。

ちょっと用事があり、今日の夜から数日間 返答できませんのでよろしく。

No. 582 # 68user 1999/12/03 (金) 18:40
> 一度の recv で全てのデータを取り出せるという保証はありません。
あ、これは
    read_size = recv(s,buf,sizeof(buf),0);
のことです。
    read_size = recv(s,buf,sizeof(buf),MSG_WAITALL);
なら、全データを待ちますので、recv は1回だけ実行すれば OK です。

ただし MSG_WAITALL を指定しても、シグナル受信・コネクション切断時は、
全データを待たずに recv から戻ります。

Prev< No. 580〜582> Next  [最新発言に戻る] [過去ログ一覧]