Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Zombie problem when creating a listening Socket (http://www.velocityreviews.com/forums/t894234-zombie-problem-when-creating-a-listening-socket.html)

vikrant 09-14-2005 11:39 AM

Zombie problem when creating a listening Socket
 
Hi

I have written a code for Listening socket(Server) that serve multiple
clients request.The Socket(Server) accept the data from clients and send
back them the same data for validation.

But,I am facing a problem while running the following code .The code
creating a Zombie for each client request.
-----------------------------------------------------------------

#!/usr/bin/perl
use IO::Select;
use IO::Socket::INET;

#LISTENING SOCKET
$sListening_Socket = new IO::Socket::INET (LocalPort => 36545,
Proto => "tcp",
Listen => 4,
Type => SOCK_STREAM)
or die "Could not create socket";

REQUEST:
while ($sNew_Socket = $sListening_Socket->accept())
{
if($iChild_Pid=fork) #Check the Child Process ID
{
close ($sNew_Socket); #Parent closes unused handle
next REQUEST;
} defined($iChild_Pid) or die "Cannot fork";

close ($sListening_Socket); #Child closes unused Handle

$obSelected_Socket = IO::Select->new($sNew_Socket);
while( $obSelected_Socket->can_read(20)) #Wait for 20 seconds
{
sysread($sNew_Socket,$sBuffer,1<<10);
$sData_Recevied.=$sBuffer;
if($sBuffer =~/\/message_end>/)
{
last;
}
}

$sNew_Socket->send($sData_Recevied);
close($sNew_Socket);
exit;
}
------------------------------------------------------------------------------------
Also,when i run the following command

ps -A|grep perl

3466 pts/1 00:00:00 perl
3469 pts/1 00:00:00 perl <defunct>
3473 pts/1 00:00:00 perl <defunct>
3478 pts/1 00:00:00 perl <defunct>
3482 pts/1 00:00:00 perl <defunct>
3486 pts/1 00:00:00 perl <defunct>
3490 pts/1 00:00:00 perl <defunct>

please known me if i am missing something.

With Regards

Vikrant

Anno Siegel 09-14-2005 11:51 AM

Re: Zombie problem when creating a listening Socket
 
vikrant <vikrantREMOVE@DELETEsaysnetsoft.com> wrote in comp.lang.perl.misc:
> Hi
>
> I have written a code for Listening socket(Server) that serve multiple
> clients request.The Socket(Server) accept the data from clients and send
> back them the same data for validation.
>
> But,I am facing a problem while running the following code .The code
> creating a Zombie for each client request.


Your code doesn't care about its kids, sure they end up becoming zombies.

Try setting $SIG{ CHLD} = 'IGNORE' in the parent. If that doesn't help,
install a reaper. Look for "zombie" and "REAPER" in perlipc for more.

Anno


[original code]
> -----------------------------------------------------------------
>
> #!/usr/bin/perl
> use IO::Select;
> use IO::Socket::INET;
>
> #LISTENING SOCKET
> $sListening_Socket = new IO::Socket::INET (LocalPort => 36545,
> Proto => "tcp",
> Listen => 4,
> Type => SOCK_STREAM)
> or die "Could not create socket";
>
> REQUEST:
> while ($sNew_Socket = $sListening_Socket->accept())
> {
> if($iChild_Pid=fork) #Check the Child Process ID
> {
> close ($sNew_Socket); #Parent closes unused handle
> next REQUEST;
> } defined($iChild_Pid) or die "Cannot fork";
>
> close ($sListening_Socket); #Child closes unused Handle
>
> $obSelected_Socket = IO::Select->new($sNew_Socket);
> while( $obSelected_Socket->can_read(20)) #Wait for 20 seconds
> {
> sysread($sNew_Socket,$sBuffer,1<<10);
> $sData_Recevied.=$sBuffer;
> if($sBuffer =~/\/message_end>/)
> {
> last;
> }
> }
>
> $sNew_Socket->send($sData_Recevied);
> close($sNew_Socket);
> exit;
> }
> ------------------------------------------------------------------------------------
> Also,when i run the following command
>
> ps -A|grep perl
>
> 3466 pts/1 00:00:00 perl
> 3469 pts/1 00:00:00 perl <defunct>
> 3473 pts/1 00:00:00 perl <defunct>
> 3478 pts/1 00:00:00 perl <defunct>
> 3482 pts/1 00:00:00 perl <defunct>
> 3486 pts/1 00:00:00 perl <defunct>
> 3490 pts/1 00:00:00 perl <defunct>
>
> please known me if i am missing something.
>
> With Regards
>
> Vikrant



--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

vikrant 09-16-2005 06:37 AM

Re: Zombie problem when creating a listening Socket
 
hi

Now, I have made some changes in the code but still facing the problem.This time the socket no more
listening to client resquests.

Changed Code is
------------------------------------------------------------------------------------------------

#!/usr/bin/perl
use IO::Select;
use IO::Socket::INET;

$sListening_Socket = new IO::Socket::INET (LocalPort => 36545,
Proto => "tcp",
Listen => 4,
Type => SOCK_STREAM
) or die "Could not create socket";

sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }
use POSIX ":sys_wait_h";
sub REAPER
{
my $child;
while (($pid = waitpid(-1,WNOHANG)) > 0)
{
logmsg "reaped $waitedpid" . ($? ? " with exit $?" : '');
}
$SIG{CHLD} = \&REAPER; # loathe sysV
}

$SIG{CHLD} = \&REAPER;
$pid=0;
while ($sNew_Socket = $sListening_Socket->accept()|| $pid)
{
next if $pid = fork;
die "fork: $!" unless defined $pid;

$obSelected_Socket = IO::Select->new($sNew_Socket);

while( $obSelected_Socket->can_read(20))
{
sysread($sNew_Socket,$sBuffer,1<<10);
$sData_Recevied.=$sBuffer;
if($sBuffer =~/\/message_end>/)
{
last;
}
}
$sNew_Socket->send($sData_Recevied);

close($sListening_Socket);
$pid=0;
exit;
} continue {
close($sNew_Socket);
}

--------------------------------------------------------------------

The OUTPUT of the Program after successful execution is:-
-----------------------------------------------------------------------------
Can't call method "send" on an undefined value at socketmodule.pl line 41.
socketmodule.pl 4031: reaped with exit 65280 at Fri Sep 16 11:51:17 2005
---------------------------------------------------------------------------------

Please correct me if i have made any mistake actually i am new to perl.

With Regards
Vikrant

Anno Siegel 09-16-2005 09:35 AM

Re: Zombie problem when creating a listening Socket
 
vikrant <vikrantREMOVE@DELETEsaysnetsoft.com> wrote in comp.lang.perl.misc:
> hi
>
> Now, I have made some changes in the code but still facing the
> problem.This time the socket no more
> listening to client resquests.
>
> Changed Code is
> ------------------------------------------------------------------------------------------------
>
> #!/usr/bin/perl


You're not using strict and warnings. Do that and declare all variables
lexically.

> use IO::Select;
> use IO::Socket::INET;
>
> $sListening_Socket = new IO::Socket::INET (LocalPort => 36545,
> Proto => "tcp",
> Listen => 4,
> Type => SOCK_STREAM
> ) or die "Could not create socket";
>
> sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }
> use POSIX ":sys_wait_h";
> sub REAPER
> {
> my $child;
> while (($pid = waitpid(-1,WNOHANG)) > 0)

^^^^
You are saving the pid to $pid.

> {
> logmsg "reaped $waitedpid" . ($? ? " with exit $?" : '');


Here you are trying to print the value of $waitedpid. Which is it?

> }
> $SIG{CHLD} = \&REAPER; # loathe sysV
> }
>
> $SIG{CHLD} = \&REAPER;
> $pid=0;
> while ($sNew_Socket = $sListening_Socket->accept()|| $pid)

^^^^^^^
What do you thin to achieve with "... || $pid"? $sNew_Socket is supposed
to be a Socket object. $pid is an integer (as far as I can see).

> {
> next if $pid = fork;


After a fork() you almost always have to branch on the value of $pid,
otherwise the same code will be run in the parent and the kid. This
seems to be what's happening here.

> die "fork: $!" unless defined $pid;
>
> $obSelected_Socket = IO::Select->new($sNew_Socket);
>
> while( $obSelected_Socket->can_read(20))
> {
> sysread($sNew_Socket,$sBuffer,1<<10);
> $sData_Recevied.=$sBuffer;
> if($sBuffer =~/\/message_end>/)
> {
> last;
> }
> }
> $sNew_Socket->send($sData_Recevied);
>
> close($sListening_Socket);
> $pid=0;
> exit;
> } continue {
> close($sNew_Socket);
> }
>
> --------------------------------------------------------------------
>
> The OUTPUT of the Program after successful execution is:-


Successful? Hmmm...

> -----------------------------------------------------------------------------
> Can't call method "send" on an undefined value at socketmodule.pl line 41.


So $sNew_Socket is undefined when the line is called. At a glance it's
hard to see how that can happen in light of the (otherwise suspect)
" ... || $pid" in the assignment. However, you are using the same
global variable $pid in the REAPER routine. That's probably where it
is set to undef.

So make the program strict- and warnings-proof and declare your variables
lexically. Then try again.

> socketmodule.pl 4031: reaped with exit 65280 at Fri Sep 16 11:51:17 2005

^^
Notice the two blanks where a pid should appear? That's because of
the the $pid/$waitedpid mixup in the REAPER routine.

Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

vikrant 09-16-2005 11:00 AM

Re: Zombie problem when creating a listening Socket
 

Thanks for correcting me.But one problem is still there.The Socket no more listening to next request
that means forking could not happened.

Suggest me the changes needs to do.So,that the code work properly.

The Code is:-
-----------------------------------------------------------------------------------------
#!/usr/bin/perl -w

use strict;
use IO::Select;
use IO::Socket::INET;

my($pid,$sBuffer,$sData_Recevied,$iZombie);

my $sListening_Socket = new IO::Socket::INET (LocalPort => 36545,
Proto => "tcp",
Listen => 4,
Type => SOCK_STREAM
) or die "Could not create socket";

sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }
use POSIX ":sys_wait_h";
sub REAPER
{

while (($iZombie = waitpid(-1,WNOHANG)) > 0)
{
logmsg "reaped $iZombie" . ($? ? " with exit $?" : '');
}
$SIG{CHLD} = \&REAPER; # loathe sysV
}

$SIG{CHLD} = \&REAPER;


while (my $sNew_Socket = $sListening_Socket->accept())
{
if (!defined($pid = fork()))
{
logmsg "cannot fork: $!";
}
elsif ($pid)
{
logmsg "begat $pid";
next;
}
my $obSelected_Socket = IO::Select->new($sNew_Socket);

while( $obSelected_Socket->can_read(20))
{
sysread($sNew_Socket,$sBuffer,1<<10);
$sData_Recevied.=$sBuffer;
if($sBuffer =~/\/message_end>/)
{
last;
}
}

$sNew_Socket->send($sData_Recevied);
close($sListening_Socket);
exit;
} continue {
close($sNew_Socket);
}
-----------------------------------------------------------------------------------------

Output is
-----------------------------------------------------------
server.pl 3618: begat 3620 at Fri Sep 16 16:23:37 2005
server.pl 3618: reaped 3620 at Fri Sep 16 16:23:37 2005
-----------------------------------------------------------

With Regards

Vikrant

Anno Siegel 09-16-2005 12:13 PM

Re: Zombie problem when creating a listening Socket
 
vikrant <vikrantREMOVE@DELETEsaysnetsoft.com> wrote in comp.lang.perl.misc:

Please show an attribution and some context with your reply.

> Thanks for correcting me.But one problem is still there.The Socket no
> more listening to next request
> that means forking could not happened.
>
> Suggest me the changes needs to do.So,that the code work properly.


I realize English is not your first language, but that sounds pretty
rude. I'm not your servant.

I can't spend the time needed to completely debug this still rather
messy program, but it seems that after the first fork the kid process
is running the main loop instead of the parent. If you comment out
the lines

# close($sListening_Socket);
# exit;

in your code you will be able to connect multiple times to your
server, but look at the log messages:

./ttt 30280: begat 30282 at Fri Sep 16 13:49:32 2005
./ttt 30282: begat 30284 at Fri Sep 16 13:50:08 2005
./ttt 30280: begat 30286 at Fri Sep 16 13:50:20 2005

Notice how the PID of the "parent"-process changes. That is not how
a server normally runs. The parent is supposed to accept() all
connections and fork off a kid to handle the actual transaction, so
the first PID should be the same in all instances.

> The Code is:-
> -----------------------------------------------------------------------------------------
> #!/usr/bin/perl -w
>
> use strict;
> use IO::Select;
> use IO::Socket::INET;
>
> my($pid,$sBuffer,$sData_Recevied,$iZombie);


This is better, but you're only halfway there.

Lexical variables should be declared as close to their first use as
possible, not all in one place. You noticed how the double use of
the variable $pid in REAPER and the main program messed up your earlier
version. The same can still happen when you declare the lexical $pid
once for the rest of the program. Declare it where it is used, not
before. The same goes for the other variables.

> my $sListening_Socket = new IO::Socket::INET (LocalPort => 36545,
> Proto => "tcp",
> Listen => 4,
> Type => SOCK_STREAM
> ) or die "Could not create socket";
>
> sub logmsg { print "$0 $$: @_ at ", scalar localtime, "\n" }
> use POSIX ":sys_wait_h";
> sub REAPER
> {
>
> while (($iZombie = waitpid(-1,WNOHANG)) > 0)
> {
> logmsg "reaped $iZombie" . ($? ? " with exit $?" : '');
> }
> $SIG{CHLD} = \&REAPER; # loathe sysV
> }
>
> $SIG{CHLD} = \&REAPER;
>
>
> while (my $sNew_Socket = $sListening_Socket->accept())
> {
> if (!defined($pid = fork()))
> {
> logmsg "cannot fork: $!";
> }
> elsif ($pid)
> {
> logmsg "begat $pid";
> next;
> }
> my $obSelected_Socket = IO::Select->new($sNew_Socket);
>
> while( $obSelected_Socket->can_read(20))
> {
> sysread($sNew_Socket,$sBuffer,1<<10);
> $sData_Recevied.=$sBuffer;
> if($sBuffer =~/\/message_end>/)
> {
> last;
> }
> }
>
> $sNew_Socket->send($sData_Recevied);
> close($sListening_Socket);
> exit;


Comment out the above two lines and watch what's happening.

> } continue {
> close($sNew_Socket);
> }


Anno
--
If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

xhoster@gmail.com 09-16-2005 04:02 PM

Re: Zombie problem when creating a listening Socket
 
vikrant <vikrantREMOVE@DELETEsaysnetsoft.com> wrote:
> hi
>
> Now, I have made some changes in the code but still facing the
> problem.This time the socket no more listening to client resquests.



You had code that was (apparently) working fine, other than that it left
zombies. Why did you competely re-write that code into this mess?

Most likely, all you had to do was add $SIG{ CHLD} = 'IGNORE'; near the top
of your code, and leave the rest of the code unchanged.

<snip tangled mess>

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB

vikrant 09-17-2005 10:02 AM

Re: Zombie problem when creating a listening Socket
 
hi Anno

>I realize English is not your first language, but that sounds pretty
>rude. I'm not your servant.


i did not did it intentionally but pardon me if i sounded a bit rude to u.

Thanks for the information and time u give to me.

With Regards

Vikrant





All times are GMT. The time now is 08:54 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.