http://www.perlmonks.org?node_id=853446

hari9 has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

I'm trying to maintain a record of how many times clients connects to a server(This information is then processed further for directing the client suitably)

I'm using hashes which has the following keys: peer_address, times_connected.

so everytime a client connects to a server, its times_connected is incremented.

And the code at the server side is as below:
my %has; while(1) { # waiting for new client connection. $client_socket = $socket->accept(); # get the host and port number of newly connected client. $peer_address = $client_socket->peerhost(); ## check against previous connections if (exists $has{$peer_address}) { $has{$peer_address}->{times_connect}=$has{$peer_address}->{tim +es_connect}+1; print "No. of Times it has communicated : $has{$peer_address}- +>{times_connect}"; } else { print "new connection\n"; $t=1; ++$has{$peer_address}; $has{$peer_address}->{times_connect}=$t; } }

Now when I run client script from one machine, I get a proper count of times_connect, but when I use the second machine to run the client code, the times_connect is getting mixed up.

in short, I'm not able to get times_connect for each client.

Any help you be great. Thanks

Replies are listed 'Best First'.
Re: Hashes for counting
by zentara (Archbishop) on Aug 06, 2010 at 18:08 UTC
    Print out some debug information in your code, like all the hash values as they come in, that way you can see what is happening.
    use Data::Dumper; $peer_address = $client_socket->peerhost(); print "peer_address\n"; ## check against previous connections if (exists $has{$peer_address}) { print "exists\n"; $has{$peer_address}->{times_connect}++; print "No. of Times it has communicated : $has{$peer_address}- +>{times_connect}"; } else { print "new connection\n"; $t=1; ++$has{$peer_address}; $has{$peer_address}->{times_connect}=$t; } } #see what you have print $DATA::Dumper(\%has),"\n";

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku
Re: Hashes for counting
by ysth (Canon) on Aug 06, 2010 at 18:29 UTC
    use strict;. It will give you an error and from that you will be able to see where you are accidentally changing a hash reference to a number. Without use strict; enabled, that number is interpreted as a new symbolic hash reference, which is not at all what you intend.
    --
    A math joke: r = | |csc(θ)|+|sec(θ)|-||csc(θ)|-|sec(θ)|| |
    Online Fortune Cookie Search
    Office Space merchandise
Re: Hashes for counting
by fullermd (Priest) on Aug 07, 2010 at 10:32 UTC

    Well, for one thing, this line:

    $has{$peer_address}->{times_connect}=$has{$peer_address}->{times_conne +ct}+1;

    is way more complicated than necessary. Firstly, you don't need the internal -> dereferences, and second, why repeat yourself instead of just using an increment?

    $has{$peer_address}{times_connect}++;

    Second, since (at least in the code you're giving) you're not tracking anything but the times_connect, you don't need that extra layer anyway; just make $has{$peer_address} the count:

    $has{$peer_address}++;

    (of course, if you're tracking more info in reality you wouldn't want to do that, but...)

    And third, since perl data structure autovivify, you don't need the branch doing special stuff based on whether $has{$peer_address} already exists. You can just do the increment unconditionally, and it'll start at 0++ (a.k.a., 1) if it's not already set.

    Since you have ++$has{$peer_address}; in your else branch, it rather reads like you sorta intended to do this in the first place, but then you do other weird stuff elsewhere...