Нужна помощь в разборе потоковых данных с сервера php socket с помощью perl - PullRequest
1 голос
/ 13 мая 2009

Я работаю над проектом для моей компании, который использует сервер сокетов (php) для сбора данных с удаленного устройства. Как сделать так, чтобы эта Perl-программа запускалась непосредственно в потоке, вместо того, чтобы сначала выполнить запись на сервер в файл tmp, затем запустить этот сценарий для этого файла, а затем записать файл csv для вставки в базу данных?

Я думал об использовании IO :: Socket, но я не уверен, как это сделать.

Кроме того, если у кого-нибудь есть какие-либо советы / указатели по очистке этого кода, это будет оценено. (Я все еще очень люблю Perl n00b; -))

Вот что у меня есть для проги perl (после запуска я получаю два файла tmp):


#vim set sw=2 ts=2
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
&convert;

#open the source file, strip out any unneeded chars, reformat the data
sub convert{
    my $source = "$ARGV[0]";
    my $dest = "$ARGV[0]"."_tmp.txt";
    chomp $source;
    open SOURCE, '', $dest or die "Could not open '$dest' $!";

    # move the data from the source file into an array
    my %fields;
    my @field_names = qw/FIELD1 FIELD2 FIELD3 FIELD4 FIELD5 FIELD6/;
    my $pack_definition = 'a4 a2 a1 a4 a4 a8A*'; 
    while(){

        # strip out the packet header 
        s#T18##g;
        s#T00##g;
        s/^(FF14).*$//g;
        s/^(FF18).*$//g;
        s/(^|\n)[\n\s]*/$1/g;

        # arrange the data into the necessary order
        @fields{@field_names} = unpack($pack_definition, $_);
        s#(FF15)(.{2})(.{1})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})#$1\t$2\t$3\t$5$4\t$7$6\t$11$10$9$8#g;
        s#(FF16)(.{2})(.{1})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})(.{2})#$1\t$2\t$3\t$4\t$5\t$6\t$7\t$8\t$9\t$10\t$11#g;
        s#(FF17)(.{2})(.{1})(.{2})(.{2})(.{2})(.{2})(.{4})(.{4})#$1\t$2\t$3\t$5$4\t$7$6\t$8\t$9#g;
        my @spds =  /(FF15)\t(.{2})\t(.{1})\t(.{4})\t(.{4})\t(.{8})/;

        # convert the data from hex to ascii
        foreach my $data (@spds){
            my $replacement = hex($data);  
            s#$data#$replacement#g;
        }
        my @psis = /(FF16)\t(.{2})\t(.{1})\t(.{2})\t(.{2})\t(.{2})\t(.{2})\t(.{2})\t(.{2})\t(.{2})\t(.{2})/;
        foreach my $data1(@psis){
            my $replacement1 = hex($data1);
            s#$data1#$replacement1#g;
        }
        my @rates=  /(FF17)\t(.{2})\t(.{1})\t(.{4})\t(.{1,4})\t(.{4})\t(.{4})/;
        foreach my $data2 (@rates){
            my $replacement2 = hex($data2);  
            s#$data2#$replacement2#g;
        }

        # print the converted data to the destination file
        print DEST;
    }
    # close the files
    close SOURCE;
    close DEST;
}
&create_vals;

# perform conversion from raw values to human readable output
sub create_vals{      
    my $source = "$ARGV[0]"."_tmp.txt";
    my $dest = "$ARGV[0]"."_converted.txt";
    chomp $source;
    open SOURCE, '', $dest or die "Cannot open '$dest' for writing $!";
    while(){
        s#(65301)\t(.{2})\t(8)\t(.{1,5})\t(.{1,5})\t(.{1,4})#"'".$1."','". $2."','". $3."','". ($4/8)."','". ($5/8)."','". ($6/20)."'"#eg;
        s#(65302)\t(.{2})\t(8)\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})\t(.{1,3})#"'".$1."','". $2."','". $3."','". $4."','". (($5*1.8)-40)."','". (($6*1.8)-40)."','". ($7*.58)."','".($8*.58)."','".($9*.29008)."','".(($10*1.8)-40)."','".$11."'"#eg;
        s#(65303)\t(.{2})\t(8)\t(.{1,5})\t(.{1,5})\t(.{1,5})\t(.{1,5})#"'".$1."','". $2."','". $3."','". ($4*0.014)."','". ($5*.05)."'"#eg;
        print DEST;
    }
}
    close SOURCE;
    close DEST;
__END__

1 Ответ

1 голос
/ 14 мая 2009

Если «запускать прямо в потоке» означает «принимать подключения от удаленного устройства вместо сервера PHP», то IO :: Socket - это путь. У Google есть множество примеров , и вы также можете просмотреть perlipc документацию.

...