httpサーバーを装ったシンプルなサーバーアプリケーションを作成します。
「サーバー」は、ローカルポート8080をリッスンし、適用するすべてのユーザーに挨拶するか、要求されたファイルが存在する場合(スクリプトサーバーが起動されたフォルダー内)のコンテンツを返します。
手始めに、シンプルで短いコード。 この段階では、コメントするために特別なことは何も必要ないので、後でコメントを残してください。
- #!/ usr / bin / perl
- LWP :: Socketを 使用し ます。
- $ headers = "HTTP / 1.1 200 OK \ r \ n Content-Type:text / html \ r \ n \ r \ n " ;
- $ sock = new LWP :: Socket ( ) ;
- $ sock- > bind ( '127.0.0.1' 、 '8080' ) ;
- $ sock- > listen ( 10 ) ;
- while ( $ socket = $ sock- > accept ( 10 ) ) {
- $ content = "Habr from Habr" ;
- $ file_name ; $ socket- > read ( \ $ file_name ) ;
- $ file_name = 〜s / GET \ /([^] *)HTTP。+ / $ 1 / s ;
- if ( open FILE 、 '<' 、 $ file_name ) {
- $ content = join "" 、 <FILE> ; FILEを閉じ ます。
- }
- $ socket- > write ( $ headers 。 $ content ) ;
- $ socket- > shutdown ( ) ;
- }
これはいコードです。書かない方がいいです。この例は、必要な機能が、必要に応じて、十分な速度で少量のコードで実装できることを示すためのものです。
このコードは、高貴で補足する必要があります。 それをもう少し読みやすくし、指定されたポートにバインドできたかどうかを確認するチェックを追加します(そうでない場合は既にビジーです)。
- #!/ usr / bin / perl
- strictを使用し ます。
- 警告を使用します 。
- LWP :: Socketを 使用し ます。
- my $ headers = "HTTP / 1.1 200 OK \ r \ n Content-Type:text / html \ r \ n \ r \ n " ;
- 私の $ sock = new LWP :: Socket ( ) ;
- die $ sock- > bind ( '127.0.0.1' 、 '8080' )で ない限り 、「ソケットをバインドできません」 ;
- $ sock- > listen ( 10 ) ;
- while ( my $ socket = $ sock- > accept ( 10 ) ) {
- 私の $ content = "Habr from Habr" ;
- 私の $ file_name ;
- $ socket- > read ( \ $ file_name ) ;
- $ file_name = 〜s / GET \ /([^] *)HTTP。+ / $ 1 / s ;
- if ( -f $ file_name and open FILE 、 '<' 、 $ file_name ) {
- $ content = join "" 、 <FILE> ;
- FILEを閉じ ます。
- }
- $ socket- > write ( $ headers 。 $ content ) ;
- $ socket- > shutdown ( ) ;
- }
- $ sock- > shutdown ( ) ;
あと数行だけですが、スクリプトはもう少し文化的になりました。
ここにあります
use LWP::Socket;
必要なモジュールを接続します。 とても使いやすいので、私はそれを選びました。
my $sock = new LWP::Socket();
ソケットを作成する
$sock->bind('127.0.0.1', '8080');
$sock->listen(10);
ソケットをローカル8080ポートにバインドし、キューの長さを設定します
while ( my $socket = $sock->accept(10) ) {
接続待ち
$ソケットに接続すると、新しいLWP :: Socket()が返されます
$socket->read( \$file_name );
$file_name =~ s/GET \/([^ ]*) HTTP.+/$1/s;
ソケットからすべてを読み取り、要求されたファイルの名前を取得します
$socket->write( $headers . $content );
ヘッダーへの書き込みとソケットへの応答
$socket->shutdown();
「セッションごと」に受信したLWPを閉じる:: Socket()
これは終了することもできますが、http-serverになりすましたいので、負荷に耐えるためにマルチスレッドが必要です:)
これを行うには、FCGI :: ProcManagerモジュールを使用します。その結果、1つの「ヘッド」プロセスと5つの子があります。 これを行うには、次の4行のみを追加します。
- #...
- LWP :: Socketを 使用し ます。
- FCGIを使用 :: ProcManager qw / pm_manage pm_pre_dispatch pm_post_dispatch / ;
- my $ headers = "HTTP / 1.1 200 OK \ r \ n Content-Type:text / html \ r \ n \ r \ n " ;
- 私の $ sock = new LWP :: Socket ( ) ;
- die $ sock- > bind ( '127.0.0.1' 、 '8080' )で ない限り 、「ソケットをバインドできません」 ;
- $ sock- > listen ( 10 ) ;
- pm_manage ( n_processes => 5 ) ;
- while ( my $ socket = $ sock- > accept ( 10 ) ) {
- pm_pre_dispatch ( ) ;
- 私の $ content = "Habr from Habr" ;
- #...
- $ socket- > shutdown ( ) ;
- pm_post_dispatch ( ) ;
- }
- $ sock- > shutdown ( ) ;
これで、「サーバー」の準備ができました。 :)を使用できます。 完全なコードを提供して、ファイルに単純にコピーし、実行し、すべてが機能することを確認できるようにします。
少し追加したこのコード:
-追加されたヘッダー
-「あいさつ」がインデックスページとして提供されます
-残りとして-何が尋ねられます
-ファイルが見つからない場合、ブラウザにこの404エラーについて通知します
-コメントを追加しました
- #!/ usr / bin / perl
- strictを使用し ます。
- 警告を使用します。
- LWP :: Socketを 使用し ます。
- FCGIを使用 :: ProcManager qw / pm_manage pm_pre_dispatch pm_post_dispatch / ;
- #ヘッダーを準備する
- my $ headers = "HTTP / 1.1%d OK \ r \ n "
- 。 「サーバー:FakeServer / 2009-09-12 \ r \ n 」
- 。 「コンテンツタイプ:text / html \ r \ n 」
- 。 「コンテンツ長:%d \ r \ n 」
- 。 「接続:閉じる\ r \ n \ r \ n 」 ;
- #ソケットを準備して開く
- 私の $ sock = new LWP :: Socket ( ) ;
- die $ sock- > bind ( '127.0.0.1' 、 '8080' )で ない限り 、「ソケットをバインドできません」 ;
- $ sock- > listen ( 10 ) ;
- #子を5つ作成する
- pm_manage ( n_processes => 5 ) ;
- #新しい接続を受け入れます
- while ( my $ socket = $ sock- > accept ( 10 ) ) {
- #子に方向を渡す
- pm_pre_dispatch ( ) ;
- #デフォルトのコンテンツ
- my $ content = "<html> <body> <h1> Habrからこんにちは</ h1> </ body> </ html>" ;
- 私の $ stat = 200 ;
- 私の $ file_name ;
- #ソケットから読み取る
- $ socket- > read ( \ $ file_name ) ;
- #必要なファイル名を取得
- $ file_name = 〜s / GET \ /([^] *)HTTP。+ / $ 1 / s ;
- if ( $ file_name ) {
- if ( -f $ file_name and open FILE 、 '<' 、 $ file_name ) {
- #ファイルから読み取る
- $ content = join "" 、 <FILE> ;
- FILEを閉じ ます。
- }
- その他 {
- $ content = "ファイルが見つかりません" ;
- $ stat = 404 ;
- }
- }
- #ヘッダーとコンテンツをソケットに入れます
- $ socket- > write ( sprintf ( $ headers 、 $ stat 、 length $ content ) ) ;
- $ socket- > write ( $ content ) ;
- $ socket- > shutdown ( ) ;
- #子供の仕事完了
- pm_post_dispatch ( ) ;
- }
- #ソケットを閉じる
- $ sock- > shutdown ( ) ;
使用説明書:
-コードをコピーしてファイルに貼り付けます
-実行(perl file.pl)
-ブラウザでhttp://127.0.0.1:8080 /を開きます
最後のオプションで誰も怖がらないことを願っています:)
PS誰かが興味を持っている場合、10人の子供を持つこのケースは15メートルのRAMを食べ、30スレッドでリクエストをテストすると、毎秒約2000リクエストを処理できました(10スレッドは既存のファイルをリクエストしました) ローカルマシンで実行し、テストでは両方のコアが天井の下にロードされました。
---------
ここからのバックライト