For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > January 2006 > millionth socket problem....









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author millionth socket problem....
.rhavin grobert

2006-01-23, 6:56 pm

hi there...

Still trying to understand perl-socket-programing, I copyied a short
skript from the perl cookbook. To test it, I checked it with telnet, so
my client *is* working.

My server is the following, and ... it doesn't work (at least not as
expected):

*****************************
#!/usr/bin/perl

use POSIX qw(:sys_wait_h);
use Socket;

# make the socket
socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
# so we can restart our server quickly
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);
# build up my socket address
$my_addr = sockaddr_in('23', INADDR_ANY);
bind(SERVER, $my_addr) or die "Couldn't bind to port 23 : $!\n";
# establish a queue for incoming connections
listen(SERVER, SOMAXCONN) or die "Couldn't listen on port $server_port
: $!\n";

sub REAPER {
1 until (-1 == waitpid(-1, WNOHANG));
$SIG{CHLD} = \&REAPER; # unless $] >= 5.002
}

$|=1;
$SIG{CHLD} = \&REAPER;
print 'setting up server'."\n";
while ($hidr = accept(CLIENT, SERVER)) {
print CLIENT "\n\r*** both talking ***\n\r";
print 'forking'."\n";
my $CPID=0;
next if $CPID = fork; # parent
print CLIENT "\n\r*** child talking ***\n\r";
die 'fork: '."$!" unless defined $CPID; # failure
# otherwise child
close(SERVER); # no use to child
$|=1;
print 'client got'."\n";
print CLIENT "\n\r*** hi & good bye! ***\n\r";
print '\n*** closing client ***'."\n";
exit; # child leaves
} continue {
print CLIENT "\n\r*** parent talking ***\n\t";
print 'parent closing client...';
close(CLIENT); # no use to parent
print '...parent done!'."\n";
}


*****************************


when im telnetting to it, it returns

*** both talking *** (just once, expected was twice)

and

*** parent talking ***

as expected, and the server itself prints 'client got' and all the
other stuff i wanted it to print.
but the 'child talking' and 'Hi & goodbye!' dont go to the client.
So my question is: what am i doing wrong? As far as I can see,
-> print CLIENT "\n\r*** parent talking ***\n\t"; <-
works well for the parent but not for the child.
Any help welcome ;-)

Jim Gibson

2006-01-23, 6:57 pm


..rhavin grobert wrote:
> hi there...
>
> Still trying to understand perl-socket-programing, I copyied a short
> skript from the perl cookbook. To test it, I checked it with telnet, so
> my client *is* working.
>
> My server is the following, and ... it doesn't work (at least not as
> expected):
>
> *****************************
> #!/usr/bin/perl
>
> use POSIX qw(:sys_wait_h);
> use Socket;
>
> # make the socket
> socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
> # so we can restart our server quickly
> setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);
> # build up my socket address
> $my_addr = sockaddr_in('23', INADDR_ANY);
> bind(SERVER, $my_addr) or die "Couldn't bind to port 23 : $!\n";
> # establish a queue for incoming connections
> listen(SERVER, SOMAXCONN) or die "Couldn't listen on port $server_port
> : $!\n";
>
> sub REAPER {
> 1 until (-1 == waitpid(-1, WNOHANG));
> $SIG{CHLD} = \&REAPER; # unless $] >= 5.002
> }
>
> $|=1;
> $SIG{CHLD} = \&REAPER;
> print 'setting up server'."\n";
> while ($hidr = accept(CLIENT, SERVER)) {
> print CLIENT "\n\r*** both talking ***\n\r";
> print 'forking'."\n";
> my $CPID=0;
> next if $CPID = fork; # parent
> print CLIENT "\n\r*** child talking ***\n\r";
> die 'fork: '."$!" unless defined $CPID; # failure
> # otherwise child
> close(SERVER); # no use to child
> $|=1;
> print 'client got'."\n";
> print CLIENT "\n\r*** hi & good bye! ***\n\r";
> print '\n*** closing client ***'."\n";
> exit; # child leaves
> } continue {
> print CLIENT "\n\r*** parent talking ***\n\t";
> print 'parent closing client...';
> close(CLIENT); # no use to parent
> print '...parent done!'."\n";
> }
>
>
> *****************************
>
>
> when im telnetting to it, it returns
>
> *** both talking *** (just once, expected was twice)
>
> and
>
> *** parent talking ***
>
> as expected, and the server itself prints 'client got' and all the
> other stuff i wanted it to print.
> but the 'child talking' and 'Hi & goodbye!' dont go to the client.
> So my question is: what am i doing wrong? As far as I can see,
> -> print CLIENT "\n\r*** parent talking ***\n\t"; <-
> works well for the parent but not for the child.
> Any help welcome ;-)


Your program worked for me, if I changed the port number to 7023, as
ports below 1024 are reserved by the system, and I telnet from the same
host using 'localhost' as a host name. You should only get "***both
talking *** once, because your program sends that to the client before
forking.

.rhavin grobert

2006-01-24, 3:55 am

> Your program worked for me, if I changed the port number to 7023, as
> ports below 1024 are reserved by the system, and I telnet from the same
> host using 'localhost' as a host name. You should only get "***both
> talking *** once, because your program sends that to the client before
> forking.


er...OK, my stupidity, ... but whats with
print CLIENT "\n\r*** child talking ***\n\r";
that doesnt come. By the way, it's a WinXP-System with ActivePerl
and telnetting to Port 23 works very well for me. But i changed the
port to
something higher and it still tells
*** both talking ***
*** parent talking ***
so where is my child? it IS printing 'client got' to the invoking
cmd-console,
so it's actually running... ...?

.rhavin grobert

2006-01-24, 7:55 am

so with some minor changes the program still has this strange
behavior. it should do the following: accept a new client (it does),
fork (it does), print with both to client. (just parent does)

the server retturns to its console the following (as expected):

setting up server
forking
[both talking] to client SCALAR(0x183f008)
[parent talking]
parent closing client......parent done!
[both talking] to client SCALAR(0x1f133c4)
[child talking]

The only difference is in the adress of the
socket-handle, but i dont know if this is a clue.

______________________________


#!/usr/bin/perl -w

use POSIX qw(:sys_wait_h);
use Socket;

# make the socket
socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
# so we can restart our server quickly
setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, 1);
# build up my socket address
$my_addr = sockaddr_in('2023', INADDR_ANY);
bind(SERVER, $my_addr) or die "Couldn't bind to port 2023 : $!\n";
# establish a queue for incoming connections
listen(SERVER, SOMAXCONN) or die "Couldn't listen on port $server_port
: $!\n";

sub REAPER {
1 until (-1 == waitpid(-1, WNOHANG));
$SIG{CHLD} = \&REAPER; # unless $] >= 5.002
}

$|=1;
$SIG{CHLD} = \&REAPER;
print 'setting up server'."\n";
while ($hidr = accept(CLIENT, SERVER)) {
print 'forking'."\n";
my $CPID=fork;
die 'fork: '."$!" unless defined $CPID; # failure
print CLIENT "\n\r*** both talking ***\n\r";
print '[both talking] to client '.\CLIENT."\n";
next if $CPID; # parent
print CLIENT "\n\r*** child talking ***\n\r";
print '[child talking]'."\n";
# otherwise child
close(SERVER); # no use to child
$|=1;
print 'client got'."\n";
print CLIENT "\n\r*** hi & good bye! ***\n\r";
print '[hi & goodbye]'."\n";
print "\n".'client exits'."\n";
exit; # child leaves
} continue {
print CLIENT "\n\r*** parent talking ***\n\t";
print '[parent talking]'."\n";
print 'parent closing client...';
close(CLIENT); # no use to parent
print '...parent done!'."\n";
}

.rhavin grobert

2006-01-24, 7:55 am

while testing this, i just noticed that close(SERVER) is
blocking. When i kill my server, the telnet client gets the
childs talking, but closing the server is something think
senseful after all i've read about in the perl cockbook.
;-\

Jim Gibson

2006-01-24, 6:56 pm

..rhavin grobert wrote:
>
> er...OK, my stupidity, ... but whats with
> print CLIENT "\n\r*** child talking ***\n\r";
> that doesnt come. By the way, it's a WinXP-System with ActivePerl
> and telnetting to Port 23 works very well for me. But i changed the
> port to
> something higher and it still tells
> *** both talking ***
> *** parent talking ***
> so where is my child? it IS printing 'client got' to the invoking
> cmd-console,
> so it's actually running... ...?


All I can tell you is that it works on my system, a Mac G4 running Mac
OS 10.4, which is a Unix-based system, and Perl 5.8.6 downloaded and
compiled on my system. Perl was originally developed for Unix systems,
so may be still a little Unix-centric. The Windows system may have
trouble emulating some Unix features individually or in tandem: sockets
and forks in this case. You might try writing a server that doesn't
fork and see if that works better. You might also try not closing the
client socket in the server parent process nor closing the server
socket in the server child process. The sample programs recommend that,
but it might be causing problems on Windows if the fork model on
Windows is different from the Unix implementation. You might also try
not writing to the client socket from the parent process, since you
would normally not do that, and it is better to restrict I/O to a
channel to one process (or is it thread on Windows?). Thankfully, I do
not do Windows programming, so can't really help you much further.

Good luck!

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com