FAQ
Hello

I have a situation where I build an anonymous array of hashes for some
requests and responses found in a file (there can be multiple requests and
responses). It works very nicely and tracks all of the responses and
requests from an ip to another IP address.

Here is my code:

my $time=$1 if /^(\d+:\d+:\d+\.\d+)/;
my $source=$1 if /(\S+) -> \S+/;
my $destination=$1 if /\S+ -> (\S+)/;
my $sourcePort=$1 if /S=(\d+)/;
my $destinationPort=$1 if /D=(\d+)/;
my $sequenceNumber=$1 if /Sequence number: (\d+)/;

if ($protocol =~ /PING REQUEST/) {
push @{$pingRequests{$destination}}, {
time => $time,
sequenceNumber=>$sequenceNumber
};
}
elsif ($protocol =~ /PING RESPONSE/) {
push @{$pingResponses{$source}}, {
time => $time,
sequenceNumber=>$sequenceNumber
};
}

I can then access the contents via code like:

foreach my $record(@{$pingRequests{$request}}) {
$requestCount++;
print "\tRequest Time=$record->{time}\n" if defined $details; }

What I want to do however is track the response time between a request and
response. This would be identified by the same sequence number for a
request/respone pair. I would like to take the time value for each and
subtract the response time from the request time to get the response time
and add that to the response hash.

I cannot figure out how to access the contents of the anonymous hash for
that one value.

Sudo code would be:

elsif ($protocol =~ /PING RESPONSE/) {
responseTime=pingRequests{$source}->time -
pingResponses{$destination)->time if pingRequests{$source}->sequenceNumber =
pingResponses{$destination}->sequenceNumber;

push @{$pingResponses{$source}}, {
time => $time,
sequenceNumber=>$sequenceNumber
responseTime=>$responseTime

};
}

DOes that make any sense? Can I do what I am trying to accomplish using the
logic above? If so, what is that syntax?

Help!

Thanks!
Jason

Search Discussions

  • Philipp Traeder at Aug 5, 2005 at 1:05 am
    On Friday 05 August 2005 01:37, Jason Normandin wrote:
    [..]
    if ($protocol =~ /PING REQUEST/) {
    push @{$pingRequests{$destination}}, {
    time => $time,
    sequenceNumber=>$sequenceNumber
    };
    }
    elsif ($protocol =~ /PING RESPONSE/) {
    push @{$pingResponses{$source}}, {
    time => $time,
    sequenceNumber=>$sequenceNumber [..]
    What I want to do however is track the response time between a request and
    response. This would be identified by the same sequence number for a
    request/respone pair. I would like to take the time value for each and
    subtract the response time from the request time to get the response time
    and add that to the response hash.

    I cannot figure out how to access the contents of the anonymous hash for
    that one value.

    Sudo code would be:

    elsif ($protocol =~ /PING RESPONSE/) {
    responseTime=pingRequests{$source}->time -
    pingResponses{$destination)->time if pingRequests{$source}->sequenceNumber
    = pingResponses{$destination}->sequenceNumber;

    push @{$pingResponses{$source}}, {
    time => $time,
    sequenceNumber=>$sequenceNumber
    responseTime=>$responseTime

    };
    }

    Hi Jason,

    I think you might want to take a look at the map function - using it, you
    could do something like this:

    my $response = $pingResponse{$destination};
    my $responseTime;
    map { $responseTime = ($response->{'time'} - $_->{'time'})
    if ($_->{'sequenceNumber'} == $response->{'sequenceNumber'})
    } @{$pingRequests{$destination}};
    DOes that make any sense? Can I do what I am trying to accomplish using the
    logic above? If so, what is that syntax?
    I'm not sure if I would approach your problem the same way - I don't know what
    exactly you need to have as result, but I would think about storing all
    request/response pairs in a hash with the sequence number as key. This might
    make things easier.

    HTH,

    Philipp
  • John W. Krahn at Aug 5, 2005 at 4:54 am

    Jason Normandin wrote:
    Hello Hello,
    I have a situation where I build an anonymous array of hashes for some
    requests and responses found in a file (there can be multiple requests and
    responses). It works very nicely and tracks all of the responses and
    requests from an ip to another IP address.

    Here is my code:

    my $time=$1 if /^(\d+:\d+:\d+\.\d+)/;
    perldoc perlsyn
    [snip]
    NOTE: The behaviour of a "my" statement modified with a statement
    modifier conditional or loop construct (e.g. "my $x if ...") is
    undefined. The value of the "my" variable may be "undef", any
    previously assigned value, or possibly anything else. Don't rely
    on it. Future versions of perl might do something different from
    the version of perl you try it out on. Here be dragons.

    So don't do that! :-)

    If you want to declare and assign from a match in one statement you have
    to do either:

    my ( $time ) = /^(\d+:\d+:\d+\.\d+)/;

    Or:

    /^(\d+:\d+:\d+\.\d+)/ and my $time = $1;

    my $source=$1 if /(\S+) -> \S+/;
    my $destination=$1 if /\S+ -> (\S+)/;
    my $sourcePort=$1 if /S=(\d+)/;
    my $destinationPort=$1 if /D=(\d+)/;
    my $sequenceNumber=$1 if /Sequence number: (\d+)/;

    if ($protocol =~ /PING REQUEST/) {
    push @{$pingRequests{$destination}}, {
    time => $time,
    sequenceNumber=>$sequenceNumber
    };
    }
    elsif ($protocol =~ /PING RESPONSE/) {
    push @{$pingResponses{$source}}, {
    time => $time,
    sequenceNumber=>$sequenceNumber
    };
    }
    You are duplicating a lot of code there. You could simplify that like:

    if ( $protocol =~ /PING RE(?:QUEST|SPONSE)/ ) {
    push @{ $pingRequests{ $destination } }, {
    time => $time,
    sequenceNumber => $sequenceNumber
    };
    }

    I can then access the contents via code like:

    foreach my $record(@{$pingRequests{$request}}) {
    $requestCount++;
    print "\tRequest Time=$record->{time}\n" if defined $details; }

    What I want to do however is track the response time between a request and
    response. This would be identified by the same sequence number for a
    request/respone pair. I would like to take the time value for each and
    subtract the response time from the request time to get the response time
    and add that to the response hash.

    I cannot figure out how to access the contents of the anonymous hash for
    that one value.

    Sudo code would be:

    elsif ($protocol =~ /PING RESPONSE/) {
    responseTime=pingRequests{$source}->time -
    pingResponses{$destination)->time if pingRequests{$source}->sequenceNumber =
    pingResponses{$destination}->sequenceNumber;

    push @{$pingResponses{$source}}, {
    time => $time,
    sequenceNumber=>$sequenceNumber
    responseTime=>$responseTime

    };
    }

    DOes that make any sense? Can I do what I am trying to accomplish using the
    logic above? If so, what is that syntax?
    The first thing you need to do is convert the time string into a number
    that can be added and subtracted and then determine how to store that in
    your structure. Something like (untested):

    use Time::Local;

    my ( $hour, $minute, $second, $fraction ) = /^(\d+):(\d+):(\d+)(\.\d+)/;

    my $time = timegm( 35, 7, 8, ( gmtime 0 )[ 3 .. 5 ] ) . $fraction;


    if ( $protocol =~ /PING REQUEST/ ) {
    $pingRequests{ $destination }{ $sequenceNumber } -= $time;
    }
    elsif ( $protocol =~ /PING RESPONSE/ ) {
    $pingRequests{ $destination }{ $sequenceNumber } += $time;
    }


    Season to taste. :-)



    John
    --
    use Perl;
    program
    fulfillment

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedAug 4, '05 at 11:37p
activeAug 5, '05 at 4:54a
posts3
users3
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase