0

以下は、HTTPリクエストを受信し、「503ServiceUnavailable」と短いメッセージを出力することを唯一の目的とするPerlスクリプトです。多くの場合、接続がリセットされ、ブラウザにエラーメッセージが表示されることを除いて、正常に動作します。これはWin32にあります。何が悪いのかわかりません。

#!/usr/local/bin/perl

use strict;
use IO::Socket::INET;
my $f = join('', <DATA>);

$SIG{CHLD} = 'IGNORE';
my $sock = IO::Socket::INET->new(ReuseAddr => 1, Listen => 512, LocalPort => 80, LocalHost => '0.0.0.0', Proto => 'tcp');
die "Cant't create a listening socket: $@" unless $sock;

while (my $connection = $sock->accept) {
    my $child;
    die "Can't fork: $!" unless defined ($child = fork());
    if ($child == 0) {
        #print "Child $$ running. ";
        $sock->close;
        do_it($connection);
        #print "Child $$ exiting.\n";
        exit 0;
    } else {
        print "Connection from ".$connection->peerhost."\n";
        $connection->close();
    }
}

sub do_it {
    my $socket = shift;
    my $pr = print $socket $f;
    if (!$pr) {
        $socket->close();
        exit(0);
    }
}

__DATA__
HTTP/1.1 503 Service Unavailable
Date: Mon, 12 Mar 2009 19:12:16 GMT
Server: Down
Connection: close
Content-Type: text/html


<html>
<head><title>Down for Maintenance</title></head>
<body>
<h2>Down for Maintenance</h2>
<p>The site is down for maintenance. It will be online again shortly.</p>
</body>
</html>
4

3 に答える 3

1

壊れたforkとして知られているWin32ではありませんか?

実際、子プロセスは親セクションとはまったく異なることを行っているため、スレッドを使用したほうがよい場合があります。

コメントの質問への回答として、すべての分岐ロジック (!!) を次のように置き換えることを考えてください。

$peer_name = $connection->peerhost();
threads->create( \&do_it, $connection );
say "Got connection from $peer_name";

(たとえば、これを参照してください。)サーバースレッド以外の場所で接続を閉じることについて心配する必要はありません。

于 2009-10-07T20:22:42.123 に答える
0

私のモジュールHTTP::Server::Brickは Windows で動作しますが、残念ながら Strawberry perl でテストがハングアップするため (todo リストにある)、手動でインストールするか、単一の perl モジュールにコピーして cpan を使用する必要があります。依存関係をインストールします。ただし、Windows の cygwin およびもちろん unix で正常にビルド/テストされます。

HTTP::Server::Brickを使用して要件を実装する方法は次のとおりです。これはかなり単純であり、スレッド/プロセスの数に上限がないという点であなたと同じ問題に苦しんでいることに注意してください。

use strict;
use warnings;

use HTTP::Server::Brick;
use HTTP::Status qw(:constants);

my $server = HTTP::Server::Brick->new( port => 80 );

my $html = join '', <DATA>;

$server->mount( '/' => {
 wildcard => 1,
 handler => sub {
  my ($req, $res) = @_;
  $res->add_content($html);
  return HTTP_SERVICE_UNAVAILABLE;
 },
   });

$server->start;

__DATA__
<html>
<head><title>Down for Maintenance</title></head>
<body>
<h2>Down for Maintenance</h2>
<p>The site is down for maintenance. It will be online again shortly.</p>
</body>
</html>

また、壊れていることが知られているウィンドウの perl fork に関するコメントについて簡単に説明します。基本的には、perl スレッドを使用して fork() 呼び出しを模倣するだけです。シームレスではありませんが、単純な状況ではスレッドを使用する簡単な方法です。

最後に、cygwin と apache または lighthttpd パッケージをインストールしたほうがよいのではないでしょうか? すべての URL に対して 503 を送信するのは、非常に短い apache 構成ファイルです。

于 2009-10-08T00:54:06.437 に答える
0

HTTP::デーモンは役に立ちますか? コアに含まれています。

Google でWindows XP SP3 の tcp 接続制限を検索した結果も関連している可能性があります。

于 2009-10-07T20:16:01.683 に答える