HTTPクライアント(並列受信)

ソケット通信によりHTTPサーバへアクセスし,指定したページをダウンロードする例題です.今回の例題では,指定したファイルに記述されたURLに並列にアクセスし,それぞれのページを保存しています.保存は,アクセスする順に [数字.html] の形式で保存されます.

ソースのダウンロード

 HTTPクライアント(並列受信)(list_87.c)
//-----------------------------------------------------------------
// 並列 HTTP クライアント
// % ./list_87 URL-listfile
//-----------------------------------------------------------------
#include <stdio.h>
#include "http_lib.h"

#define MAX_URL 10

int main(int argc, char *argv[])
{
    FILE *fp;
    int i,ri,n_url,read_size,r_head;
    int s,pid,status;
    unsigned short port=0; // 接続するポート番号
    char url[MAX_URL][URL_LEN];
    char outfile[URL_LEN];
    char host[URL_LEN];    // 接続するホスト名
    char path[URL_LEN];    // 要求するパス
    char buf[BUFSIZ];

    if(argc != 2) {
        printf("usage: %s URL-listfile\n",argv[0]); return 0;
    }
    // URL 情報の取得
    if((fp=fopen(argv[1],"r")) == NULL){
        perror(argv[1]); return 0;
    }
    i=0;
    while(fgets(url[i],URL_LEN,fp)){
        read_size = strlen(url[i]);
        if(url[i][read_size-1] == '\n')
            url[i][read_size-1] = '\0';
        i++;
    }
    n_url = (i>MAX_URL)?MAX_URL:i;
    fclose(fp);
    // 並列 wcat
    for(i=0;i<n_url;i++){
        // プロセスの作成
        if((pid = fork()) < 0){ perror("fork"); continue; }
        // 子プロセス
        if(pid == 0){
            if(!split_url(url[i],host,path,&port)){
                fprintf(stderr,"[%d]:%s を取得します.\n\n",i,url[i]);
                // サーバに接続
                if((s = http_open(host,port)) < 0) exit(0);
                // サーバに受信要求
                http_request(s,host,path,port);
                // 受信&保存
                r_head = 1;
                sprintf(outfile,"%d.html",i);
                if((fp=fopen(outfile,"w+")) == NULL) exit(0);
                while(1){
                    read_size = read(s,buf,BUFSIZ);
                    if(read_size > 0){
                        for(ri=0;ri<read_size;ri++){
                            if(r_head == 1){ // ヘッダ部の無視
                                if(!strncmp(buf+ri,"\r\n\r\n",4)){
                                    ri+=4; r_head = 0;
                                }
                            } else {
                                if(buf[ri] != '\r') fputc(buf[ri],fp);
                            }
                        }
                    } else break;
                }
                fclose(fp);
                fprintf(stderr,"[%d]:完了.\n",i);
                // 後始末
                close(s);
            }
            exit(0);
        }
    }
    for(i=0;i<n_url;i++){
        if(wait(&status) < 0){
            perror("wait"); exit(1);
        }
    }
    return 0;
}

実行結果
Gami[203]% ./mwcat.exe
usage: ./mwcat URL-listfile
Gami[204]% cat url.txt  --> URL を保存したリストファイル
http://www-cc.ee.tokushima-u.ac.jp/~a-gamyl/index.html
http://www.yahoo.co.jp/
http://www.google.com/intl/ja/
http://www.msn.co.jp/home.armx
http://www.biglobe.ne.jp/
Gami[205]% ./mwcat.exe url.txt
[0]:http://www-cc.ee.tokushima-u.ac.jp/~a-gamyl/index.html を取得します.

[1]:http://www.yahoo.co.jp/ を取得します.

[2]:http://www.google.com/intl/ja/ を取得します.

[3]:http://www.msn.co.jp/home.armx を取得します.

[4]:http://www.biglobe.ne.jp/ を取得します.

[0]:完了.
[2]:完了.
[1]:完了.
[4]:完了.
[3]:完了.
Gami[206]%
inserted by FC2 system