Monthly Archives: 5月 2011

Perlで簡易WEBサーバを書く

なんとなく書いてみました。リファラやユーザエージェントとかそんなものは環境変数として取得できませんしForkもしません。とりあえず動かして一対一でHTMLファイルや画像ファイルを表示するだけです。ファイヤウォールを外せば他のパソコンからも閲覧できたりします。(危ないのでやらないようにw)

#!/usr/bin/perl -w
use FindBin;
use Socket qw/sockaddr_in inet_ntoa/;
use HTTP::Daemon;
use HTTP::Status;
 
# バッファリングしない
local $| = 1;
# 公開パス
my $public_path = "$FindBin::Bin"."/public_html";
my %in; # ブラウザからデータを受け取るハッシュを初期化

my $daemon = HTTP::Daemon->new(LocalAddr => '',LocalPort => "8080");
print "START SERVER $public_pathn";

while (my ( $client, $peer_addr ) = $daemon->accept){ # メインループ

    my ( $port, $iaddr ) = sockaddr_in($peer_addr); # PortとIPを取得する
    my $remote_addr = inet_ntoa($iaddr); # バイナリ状態のIPを変換する
    print "Access IP: $remote_addrn";

    while (my $request = $client->get_request){ # リクエスト処理ループ

        if ($request->method eq 'GET'){

            my $resource = $request->url->path;

            # GETで送られてきた情報を取得
            my $get_request = $request->url;
            my $get_data = ""; $get_data = $1 if($get_request =~ m/.*?(.+)/);
            &get_form($get_data) if($get_data);
            
            print "---> PATH: $resource GET: $get_datan";
            foreach my $key (keys (%in)){print "------> HASH: $key -> $in{$key}n";}

            if($resource =~ m/^/-_-/){ # インフォメーションページ
                my $header = HTTP::Headers->new( 'Content-Type' => 'text/html' );
                my $res = HTTP::Response->new( 200, 'OK', $header );
                $client->send_response($res);
                print $client "日本語でおk? PATH: $resource GET: $get_data IP: $remote_addrn";
            }elsif($resource =~ m//$/){ # ファイル名を省略していたらとりあえず"index.html"を表示する
                $client->send_file_response($public_path.$resource."index.html");
            }else{ # それ以外はファイルを探して表示
                $client->send_file_response($public_path.$resource);
            }

        }

    }

    $client->close;

}

sub get_form{
	%in = (); my ($get_data) = @_ ;
	foreach my $data (split(/&/, $get_data)) {
		my ($key, $value) = split(/=/, $data);

		$value =~ s/+/ /g;
		$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
		$value =~ s/t//g;

		$in{"$key"} = $value;
	}
}

ブラウザで適当にhttp://127.0.01:8080/-_-/ でアクセスすれば下記のような返答があると思います。
日本語でおk? PATH: /-_-/ GET: IP: 127.0.0.1

P7H55-M BIOS設定

BIOS SETUP UTILITY を起動させる。

とりあえず言語設定ができるようなので設定する。
MainのLanguage [English]を[日本語]へ。

オンボードGPU(iGPU)を使う設定を行う(PCI-E x16にRAIDカードを挿すとグラフィックボードと誤認するため)
詳細設定からInitiate Graphic Adapter を[PCI/iGPU]を選択。(何故か[iGPU]ではうまく動作しなかった。)

起動時にIDE用ディバイスを使わないのにスキャンされるのでスキャンしないようにする。
詳細設定からオンボードディバイス設定構成を選択しVT6415 IDE Controllerを[無効]にする。

停電時、電源復旧で自動起動するように設定する。(自動動時に確認としてF2を押すように促す保護機能を外す。)
電源からAnti Sure Supportを[無効]に設定。
APM Configurationを選択しAC 電源切断後の復旧モードを[Power On]に設定する。

RAIDカードの設定はHP SC40Geホスト バス アダプタ リファレンス ガイドを見る。
普段はこんな事はまとめないですが複数導入する予定なので次設定するとき設定し忘れが無いようにww

P7H55-M + i3(内蔵GPU) + CentOS5

先日記述したとおりのパーツがひと通り揃った(RAIDカードは注文中なので除く)ので仮組みしてみました。

結論的には何も問題はありませんでした。

ただ、CentOS5.4ではNICやGPUにドライバが認識しませんでしたがCentOS5.6では普通に認識しました。

__追記__

HP SC40Ge(SAS3042EL)も設定すれば問題なく使える事が分かりました。

自作サーバの構成予定

8月ぐらいには構築したいので構成を決めて想定されるなるべく正確な金額をだしてみました。
=========================================
ハードディスク
=========================================
Yahoo!オークション(ID:************)
WD3200JS 2,799円 x 4 *
送料 945円 *

合計 13,120円 *
=========================================

=========================================
一般ユーザ向けサーバ
=========================================
ドスパラ
SILVERSTONE SST-GD05B 7,980円 *
HuntKey Jumper350 350W 3,980円 *
送料 740円 *

BESTDO! 通販部
P7H55-M 5,940円 *
送料 740円 *

Yahoo!オークション(ID:************)
HP SC40Ge(SAS3042EL) 3,990円 *
通常プラッタへの加工費 1,000円 *
SFF-8484 to SATAのケーブル 1,400円 *
送料 740円 *

合計 25,770円 *
=========================================

=========================================
高負荷CGI専用サーバ
=========================================
購入予定
=========================================
EC-JOY
Core i5 680 BOX 25,679円
送料 450円

TSUKUMO
CMX8GX3M2A1600C9 8,380円
送料 0円

ドスパラ
SILVERSTONE SST-GD05B 7,980円
HuntKey Jumper350 350W 3,980円
送料 740円

BESTDO! 通販部
P7H55-M 5,940円
送料 740円

Yahoo!オークション(ID:************)
HP SC40Ge(SAS3042EL) 3,990円
通常プラッタへの加工費 1,000円
SFF-8484 to SATAのケーブル 1,400円
送料 740円

合計 61,019円
=========================================

* 印 購入完了

全て合わせて大体10万円くらいでしょうか高いです・・・当初の予想より遥かに高い金額・・・
それでも毎月何もしなくても3万円ほどの電気代が飛んでいることを考えれば・・・

省エネで処理能力を落とさず冗長性を保ち、なおかつLinuxに対応させる構成を決めるのは予想以上に大変です。
誰かマジで寄付してください!いくらでも喜びます>ω<。

二分探索の処理の様子を細かく見てみる

二分探索の仕組みを詳しく見てみようと思う。サンプルコードはPerlで書いているがCやRuby、Javaなどほかの言語も似たようなものだと思う。

サンプルコード

#!/usr/bin/perl -w

# パラメータ
my $left = 0; my $right = 100; my $target = 140;
my @a; # 初期化

# 0~100までの数字を二倍しながら配列@aに追加
foreach my $i ($left..$right) {push(@a,$i*2);}

# 配列@aのリファレンスとその他引数を添えて二分探索関数を実行する
print &binary_search (@a , $left , $right , $target);

sub binary_search{
	# 配列@aのリファレンスと引数の受け取り
	my ($a , $left , $right , $target) = @_;
	# リファレンス$aを使い配列@aを読み込む
	my @a = @{$a};
	while($left <= $right){
		my $mid = int(($left + $right) / 2);
		if($a[$mid] == $target){
			return $mid;
		}elsif($a[$mid] < $target){
			$left = $mid + 1;
		}else{
			$right = $mid - 1;
		}
	}
	return -1;
}

変数や条件式の動きを追ってみると次のようになっていることが分かる。

$left $right $mid if($a[$mid] == $target)
0 100 (0 + 100) / 2 = 50 100 < 140 → 50 + 1 ($left)
51 100 (51 + 100) / 2 = 75 150 > 140 → 75 – 1 ($right)
51 74 (51 + 74) / 2 = 62 126 < 140 → 62 + 1 ($left)
63 74 (63 + 74) / 2 = 68 137 < 140 → 68 + 1 ($left)
69 74 (69 + 74) / 2 = 71 143 > 140 → 71 – 1 ($right)
69 70 (69 + 70) / 2 = 69 139 > 140 → 69 + 1 ($right)
70 70 (70 + 70) / 2 = 74 140 == 140 → END

二分探索の仕組みも分かったがPerlのリファレンスについても勉強になった。
一石二鳥ですね~