Client socket programming eating up CPU/memory

S

Stryder

I'm trying to write a client program that when called upon will create
a socket, connect to a remote server, send a request and get back data,
then close the socket.

I'm able to do all of this but each subsequent socket I create causes
the program to eat up more memory and CPU cycles. I've copied the
examples directly from the Camel book and other places, and this always
happens. I've encountered this on both Solaris and Linux with both
IO::Socket and IO::Socket::INET modules.

Here's some code that is causing this to happen. I'll follow it with
some "top" readings that show the memory and CPU usage increasing.

========================= CODE ==============================
use IO::Socket;
use IO::Handle;

############## irrelevant code populating @unaps here

my $paddr = sockaddr_in(9000, inet_aton('127.0.0.1')) || die
"sockaddr_in error: $!";
my $buff;

foreach $unap ( @unaps ) {
$remote = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => '127.0.0.1',
PeerPort => 9000,
);
unless ($remote) { die "cannot connect to http daemon on $host" }
$remote->autoflush(1);

print $remote "$unap\x0d\x0a";
$buff = <$remote>;
while (<$remote>) {}
close $remote;
print "$buff\n";
}

========================= END CODE ==============================

Here's the "top" readout. Each of these readings is just a few seconds
apart.

20001 gatekeep 1 10 0 27M 27M cpu/1 0:06 11.93% perl
20001 gatekeep 1 30 0 30M 29M run 0:07 13.25% perl
20001 gatekeep 1 10 0 32M 32M cpu/2 0:08 14.21% perl
20001 gatekeep 1 30 0 34M 34M cpu/2 0:08 15.01% perl
20001 gatekeep 1 20 0 36M 35M run 0:09 15.89% perl
20001 gatekeep 1 30 0 38M 38M cpu/1 0:10 16.94% perl
20001 gatekeep 1 30 0 40M 39M run 0:11 17.79% perl
20001 gatekeep 1 10 0 42M 42M sleep 0:12 18.64% perl
20001 gatekeep 1 0 0 44M 43M run 0:13 19.38% perl
20001 gatekeep 1 30 0 46M 45M run 0:14 20.42% perl
20001 gatekeep 1 10 0 47M 47M run 0:14 21.07% perl
20001 gatekeep 1 0 0 49M 49M cpu/1 0:15 21.69% perl
20001 gatekeep 1 40 0 51M 51M cpu/2 0:16 22.49% perl
20001 gatekeep 1 30 0 52M 52M cpu/1 0:17 22.67% perl
20001 gatekeep 1 10 0 54M 54M cpu/1 0:17 23.12% perl
20001 gatekeep 1 50 0 56M 56M sleep 0:18 23.62% perl
20001 gatekeep 1 30 0 59M 59M sleep 0:20 24.30% perl
20001 gatekeep 1 50 0 65M 65M cpu/2 0:23 25.59% perl
20001 gatekeep 1 30 0 67M 66M cpu/1 0:23 26.17% perl
20001 gatekeep 1 0 0 68M 68M cpu/2 0:24 26.62% perl
20001 gatekeep 1 40 0 70M 70M cpu/1 0:25 27.38% perl
20001 gatekeep 1 20 0 72M 72M cpu/2 0:27 28.04% perl
20001 gatekeep 1 10 0 74M 73M sleep 0:27 28.24% perl
20001 gatekeep 1 0 0 75M 75M cpu/2 0:28 28.58% perl
20001 gatekeep 1 10 0 77M 77M cpu/1 0:29 29.10% perl
20001 gatekeep 1 0 0 79M 78M cpu/1 0:30 29.31% perl

I'm hoping this is just something dumb I'm not understanding about
this. Any help would be VERY appreciated.

Thanks.

Ralph
 
A

A. Sinan Unur

========================= CODE ==============================

use strict;
use warnings;
use IO::Socket;
use IO::Handle;

############## irrelevant code populating @unaps here

my $paddr = sockaddr_in(9000, inet_aton('127.0.0.1')) || die
"sockaddr_in error: $!";
Why?

my $buff;

You should declare variables in the smallest applicable scope.
foreach $unap ( @unaps ) {

for my $unap ( @unaps ) {
$remote = IO::Socket::INET->new(

my $remote = ...;
Proto => "tcp",
PeerAddr => '127.0.0.1',
PeerPort => 9000,
);
unless ($remote) { die "cannot connect to http daemon on $host" }
$remote->autoflush(1);

print $remote "$unap\x0d\x0a";

See, we have no idea what $unap is.
$buff = <$remote>;

Probably my $buf = ...;
while (<$remote>) {}

Well, do you know if the server ever stops sending data?
close $remote;
print "$buff\n";
}

It is very hard for me to figure out what the real problem is because
there is no way to test this. Why not try and come up with the shortest
possible script that still exhibits the problem.

Please do read the posting guidelines for this group for valuable
information on how you can help others help you.

Sinan
 
X

xhoster

Stryder said:
========================= CODE ==============================
use IO::Socket;
use IO::Handle;

############## irrelevant code populating @unaps here

my $paddr = sockaddr_in(9000, inet_aton('127.0.0.1')) || die
"sockaddr_in error: $!";

What does this do?
my $buff;

foreach $unap ( @unaps ) {

You should use strict, not that that matters.
$remote = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => '127.0.0.1',
PeerPort => 9000,
);
unless ($remote) { die "cannot connect to http daemon on $host" }

There is not variable named $host used elsewhere in your code.
$remote->autoflush(1);

print $remote "$unap\x0d\x0a";
$buff = <$remote>;
while (<$remote>) {}
close $remote;
print "$buff\n";
}

There is nothing in this code that would prevent it from using all the CPU
it can get, other than slowness on the part of the other end of the socket.

========================= END CODE ==============================

Here's the "top" readout. Each of these readings is just a few seconds
apart.

20001 gatekeep 1 10 0 27M 27M cpu/1 0:06 11.93% perl
20001 gatekeep 1 30 0 30M 29M run 0:07 13.25% perl
20001 gatekeep 1 10 0 32M 32M cpu/2 0:08 14.21% perl
20001 gatekeep 1 30 0 34M 34M cpu/2 0:08 15.01% perl
20001 gatekeep 1 20 0 36M 35M run 0:09 15.89% perl ....

I'm hoping this is just something dumb I'm not understanding about
this. Any help would be VERY appreciated.


My guess is that the problem is in your server, not your client. If the
server is throwing increasing amounts of crap at the client, the client
needs to use increasing amounts of CPU and memory to deal with it.


Xho
 
S

Stryder

Problem solved. Read on if you're interested.

Thanks for the replys.

As I said in the original post, I tried creating sockets in a loop with
several sets of example code cut and pasted from perlipc, the Camel
book and other places, altered slightly to loop through my data. I
also tried it on Solaris and Linux and against several different
servers. The bottom line is it shouldn't have been happening.

I found another posting complaining about the same thing. He said he
upgraded from Perl 5.8.0 to 5.8.2 and the problem went away. So I
upgraded from 5.8.0 to 5.8.6 on Solaris and ran the exact same code,
and sure enough the problem went away.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top