Откопал сорец месячной давности...)
Полноценный объектный модуль для организации сервера распределенных вычислений (если точнее брут мд5). Я тут подумал... Через пару дней напишу Pod доку для него и скину.
Код в принципе не сложный, думаю разберетесь.
Ежели какие вопросы - пишите тут.
Полноценный объектный модуль для организации сервера распределенных вычислений (если точнее брут мд5). Я тут подумал... Через пару дней напишу Pod доку для него и скину.
Код в принципе не сложный, думаю разберетесь.
Ежели какие вопросы - пишите тут.
Код:
package Distributed;
use strict;
use vars qw($VERSION @ISA @EXPORT_OK);
use IO::Socket;
use threads;
$VERSION="0.01";
@ISA=qw(IO::Socket threads);
@EXPORT_OK=qw(host port logFile clientsFile taskFile foundFile maxClients DEBUG);
sub new
{
my($class,%args)=@_;
my $self={%args};
if(!exists($self->{host})) { $self->{host}="127.0.0.1" }
if(!exists($self->{port})) { $self->{port}=31337 }
if(!exists($self->{logFile})) { $self->{logFile}="server.log" }
if(!exists($self->{clientsFile})) { $self->{clientsFile}="clients.dat" }
if(!exists($self->{taskFile})) { $self->{taskFile}="clients.dat" }
if(!exists($self->{foundFile})) { $self->{foundFile}="found.dat" }
if(!exists($self->{maxClients})) { $self->{maxClients}=10 }
if(!exists($self->{DEBUG})) { $self->{DEBUG}=0 }
return bless($self,ref($class)||$class);
}
sub startServer
{
my $self=shift;
print "Debug: starting server\n" if $self->{DEBUG};
my $i=0;
my $socket=IO::Socket::INET->new(LocalAddr=>scalar($self->{host}),
LocalPort=>int($self->{port}),
Listen=>int($self->{maxClients}),
Proto=>"tcp",
Type=>SOCK_STREAM,
Blocking=>0)||exit print __FILE__.": ".__LINE__.": can not create socket: ".$!."\n";
while(1)
{
next unless(my $newConnection=$socket->accept());
my $clData=threads->create(\&processClient,$i,$newConnection)->detach();
if($clData eq "processed") { $self->logAction($newConnection->peer()." was processed\n"); }
elsif($clData eq "found") { $self->logAction($newConnection->peer()." found the password for task=".$i++."\n"); }
else { $self->logAction($newConnection->peer()." was failed to process\n"); }
}
}
sub logAction
{
my($self,$action)=@_;
print "Debug: logging\n" if $self->{DEBUG};
open(LOG,">>$self->{logFile}")||exit print __FILE__.": ".__LINE__.": can not open logfile: ".$!."\n";
print LOG localtime()." - ".$action."\n";
close LOG;
}
sub processClient
{
my($self,$clCtr,$conn)=@_;
print "Debug: client connected\n" if $self->{DEBUG};
my($response,@splitResponse);
my @idArr=split('\.',$conn->peer());
my $id=$idArr[2].$idArr[3];
undef @idArr;
$conn->recv($response,128);
@splitResponse=split(':',$response);
if($splitResponse[0] eq "COMMAND"&&$splitResponse[1] eq "OLD")
{
if($self->verifyClient($id) eq "success")
{
$conn->send("STATUS:OK",0,0);
$conn->recv($response,128);
@splitResponse=(':',$response);
if($splitResponse[0] eq "TASK"&&$splitResponse[1] eq "GET")
{
my @task=getTask($clCtr);
foreach(@task) { $conn->send($_,0,0); sleep(1); }
$conn->recv($response,128);
if($response eq "STATUS:OK")
{
close $conn&&undef $conn;
return "processed";
}
else { return "failed"; }
}
elsif($splitResponse[0] eq "STATUS")
{
if($splitResponse[1] eq "FOUND")
{
open(FOUNDDB,">>$self->{foundFile}")||exit print __FILE__.": ".__LINE__.": can not open passwords file: ".$!."\n";
print FOUNDDB "Hash:".$splitResponse[2]." Password: ".$splitResponse[3]."\n";
close FOUNDDB;
close $conn&&undef $conn;
open(TASKDB,">>$self->{taskFile}")||exit print __FILE__.": ".__LINE__.": can not open tasks database: ".$!."\n";
while(<TASKDB>)
{
if(/$splitResponse[2]/) { next; }
else { print TASKDB $_; }
}
close TASKDB;
return "found";
}
elsif($splitResponse[1] eq "NOTFOUND")
{
$conn->send("STATUS:OK");
$conn->recv($response,128);
if($response eq "TASK:GET")
{
my @task=getTask($clCtr);
foreach(@task) { $conn->send($_,0,0); sleep(1); }
$conn->recv($response,128);
if($response eq "STATUS:OK")
{
close $conn&&undef $conn;
return "processed";
}
else
{
close $conn&&undef $conn;
return "failed";
}
}
else
{
close $conn&&undef $conn;
return "failed";
}
}
else
{
close $conn&&undef $conn;
return "failed";
}
}
else
{
close $conn&&undef $conn;
return "failed";
}
}
else
{
close $conn&&undef $conn;
return "failed";
}
}
}
sub regNewClient
{
my($self,$id)=@_;
print "Debug: processing *new* client\n" if $self->{DEBUG};
open(CLBD,$self->{clientsFile})||exit print __FILE__.": ".__LINE__.": can not open clients database: ".$!."\n";
print CLBD $id."\n";
close CLBD;
print "Debug: *new* client have been added to database with id=".$id."\n";
}
sub verifyClient
{
my($self,$id)=@_;
print "Debug: verifieng client with id=".$id."\n" if $self->{DEBUG};
open(CLIENTSDB,$self->{clientsFile})||exit print __FILE__.": ".__LINE__.": can not open clients database: ".$!."\n";
while(<CLIENTSDB>)
{
chomp($_);
close CLIENTSDB&&return "success" if($_ eq $id);
}
close CLIENTSDB&&return "failed";
}
sub getTask
{
my($self,$taskId)=@_;
print "Debug: getting a piece of task with id=".$taskId."\n" if $self->{DEBUG};
my($taskReady,$currClientsNum)=0;
my($id,$hash,$length,$charset,$range,$allVariants) ;
open(TASKDB,$self->{taskFile})||exit print __FILE__.": ".__LINE__.": can not open tasks database: ".$!."\n";
open(CLIENTSDB,$self->{clientsFile})||exit print __FILE__.": ".__LINE__.": can not open clients database: ".$!."\n";
$currClientsNum++ while(<CLIENTSDB>);
close CLIENTSDB;
while(<TASKDB>)
{
if(/^$taskId;/)
{
chomp($_);
($id,$hash,$length,$charset)=split(';',$_);
for(my $i=1;$i<=$length;$i++) { $allVariants.=$i**length($charset) }
$range=int($allVariants/$currClientsNum);
$taskReady=1;
}
}
if($taskReady==0)
{
print __FILE__.": ".__LINE__.": no task with id=".$taskId."\n";
return "failed";
}
close TASKDB;
return my @retData=("TASK:HASH:".$hash,
"TASK:LENGTH:".$length,
"TASK:CHARSET:".$charset,
"TASK:RANGE:".$range);
}
1; # Единичка! Я закончил писать;)
# Distributed.pm
# (C)oded by .:[KSURi]:.
# http://cup.su/