Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Need help with a simple UNIX sockets server based on IO::Socket::UNIX
Hi. I've tried to create a simple client + server that communicate
through a unix socket.

As with all socket servers, it has a loop where it waits for
connections:

while ($client = $sock->accept()) {
# handle client here
}

The problem is that $sock->accept() is returning undef on each
alternate client connection with error "No child processes".

I made this temporary workaround that does work but of course I must be
screwing up somewhere else:

while ($client = $sock->accept() || $client = $sock->accept()) {
# handle client here
}

I hope someone can help or provide an example. I've included the client
+ server code below for those who are interrested in taking a p.

Thanks,
Craig Manley

############ client ############
#!/usr/bin/perl -w
use strict;
use IO::Socket;

my $sockname = 'mysocket';

my $client = IO::Socket::UNIX->new('Peer' => $sockname,
'Type' => SOCK_STREAM,
'Timeout' => 50) or die "$0: error
connecting to '$sockname': $ [at] \n";
my $pid = fork();
unless(defined($pid)) {
die("Fork this! I cannot forking fork!\n");
}
if ($pid) {
write_sock();
waitpid($pid, 0);
}
else {
read_sock();
}

sub write_sock {
for (1..10) {
print $client "testline number $_\n"; # print to socket
}
print $client "\n"; # empty line causes server to terminate
connection
print "Done writing.\n"; # (goes to stdout, not socket)
}

sub read_sock {
while (my $line = <$client> ) {
print $line; # report to stdout
# simulate someone reading slooowly (50ms/line):
select(undef, undef, undef, 0.05);
}
}




########### server ############
#!/usr/bin/perl -w
use strict;
use IO::Socket;
use POSIX ":sys_wait_h"; # (for WNOHANG)
use Data::Dumper qw(Dumper);

# example using unix domain socks
# once the file is created as a socket, any client can
# interact with it

my $sockname = 'mysocket';


service_clients( get_sock() ); # wait for incoming requests


sub get_sock {
unlink $sockname;
my $sock = IO::Socket::UNIX->new('Local'  => $sockname,
'Type'   => SOCK_STREAM,
'Listen' => SOMAXCONN) || die "$0:
error starting daemon on '$sockname': $ [at] \n";
# you might want to change permissions and ownership, e.g.:
#chmod 0600, $sockname;
#chown scalar getpwnam('nobody'), 0, $sockname;
return $sock;
}

sub service_clients {
my $sock = shift;
$SIG{CHLD} = \&reaper;
my $client;
while ($client = $sock->accept()) { # Why the hell does it return
undef on the next iteration?
# while ($client = $sock->accept() || $client = $sock->accept()) { #
This strangely enough does work.

# fork yet another process to prevent buffer deadlock. one proc
writes to
# the sock, the other reads the deamons response
my $pid = fork();
unless(defined($pid)) {
die("Fork this! I cannot forking fork!\n");
}
if ($pid) { # parent
print "$pid $$: I'm the parent and am going to wait for another
client.\n";
close($client); # no use to parent
next; # be ready for another client
}
print "$pid $$: I'm the child and I'm going to service the
client.\n";
# child
close($sock); # no use to child
process_requests($client);
print "$pid $$: I'm the child and I'm going to exit.\n";
exit; # terminate child
}
print "Damnit! I'm the server and I finished unexpectedly: $!\n";
}

sub process_requests {
my $client = shift;
$0 = "unixsockd: handling requests...";
# read from client until empty line which causes it to close
connection
while ( my $line = <$client> ) { # read line from socket
if ($line =~ /^\s$/) {
last; # exit on empty line
}
chomp($line);
# put some more useful code here to read each line or whatever...
printf $client "%s: %s, handled by PID %d\n",
scalar localtime(time), $line, $$;
# return something to client
}
}

sub reaper {
while (waitpid(-1,WNOHANG) > 0) {}
$SIG{CHLD} = \&reaper;
}


Report this thread to moderator Post Follow-up to this message
Old Post
Craig Manley
04-14-05 01:55 PM


Re: Need help with a simple UNIX sockets server based on IO::Socket::UNIX
Oops sorry, the working workaround (not solution) is this:
while (($client = $sock->accept()) || ($client = $sock->accept())) {
...
}


Report this thread to moderator Post Follow-up to this message
Old Post
Craig Manley
04-14-05 01:55 PM


Re: Need help with a simple UNIX sockets server based on IO::Socket::UNIX
Oops sorry, the working workaround (not solution) is this:
while (($client = $sock->accept()) || ($client = $sock->accept())) {
...
}


Report this thread to moderator Post Follow-up to this message
Old Post
Craig Manley
04-16-05 08:56 AM


Re: Need help with a simple UNIX sockets server based on IO::Socket::UNIX
"Craig Manley" <glideraerobatics@hotmail.com> wrote in message
news:1113469375.529616.222890@o13g2000cwo.googlegroups.com...
> Hi. I've tried to create a simple client + server that communicate
> through a unix socket.
>

What you have provided doesn't look all that simple to me. At its simplest a
server script (which listens eternally, but can accept only one connection
at a time) could look like this:

-------------------------------------------
use strict;
use IO::Socket;

my ($client, $data_read);

# Server listens at port 2009, for example.
my $server = IO::Socket::INET->new(LocalPort => 2009,
Type      => SOCK_STREAM,
Reuse     => 1,
Listen    => 1 )
or die "Couldn't be a tcp server on port 2009: $!\n";

while(1) {
print "Server waiting\n";
$client = $server->accept();

$data_read = <$client>;  # Expects a single line

# Do something with the message received from client -
# in this case echo the message back.
print $client $data_read;

close($client);
}
__END__
----------------------------------

and an (also eternal) client script could look like this:

------------------------------------
use strict;
use warnings;
use IO::Socket;

my $remote;
my $port = 2009; #  port at which server listens
my $host = '192.168.0.2'; # server's address

while(1) {

$remote = IO::Socket::INET->new( Proto    => "tcp",
PeerAddr => $host,
Type     => SOCK_STREAM,
PeerPort => $port);

unless ($remote) {
die "cannot connect to http daemon on $host\n$!\n";
}

# This particular script sits here, waiting for input ....
my $data_to_send = <STDIN>;

print $remote "$data_to_send\n"
or die "Unable to send: $!\n";

# Cater for a multiline reply from the server
my $data_received = '';
while(<$remote> ) {$data_received .= $_}

# Do something with the reply -
# in his case simply print out the reply
print $data_received, "\n";

close($remote);
}
__END__
---------------------------------------------

That's taken from actual scripts that I use on linux, but they have been
modified - which means that I could have rendered them unusable (through
some stupid error).

You'll note that there's no use of IO::Socket::UNIX. Do you need to use that
module ? If so, and you strike difficulty modfiying the above script(s),
then let us know.
There's also no forking. Do you need to fork ? Even if you do, you'll
probably find it useful to get your script working under a scenario where
forking is not required, and then develop it to incorporate forking.

Hth.

Cheers,
Rob



Report this thread to moderator Post Follow-up to this message
Old Post
Sisyphus
04-17-05 08:55 PM


Re: Need help with a simple UNIX sockets server based on IO::Socket::UNIX
"Craig Manley" <glideraerobatics@hotmail.com> wrote:
> Hi. I've tried to create a simple client + server that communicate
> through a unix socket.
>
> As with all socket servers, it has a loop where it waits for
> connections:
>
> while ($client = $sock->accept()) {
>   # handle client here
> }
>
> The problem is that $sock->accept() is returning undef on each
> alternate client connection with error "No child processes".

This is just a wild guess, but I think that what is happening is that
your $sock->accept call is being interupted by the SIGCHLD, and is not
getting automatically restarted once the sig handler finishes.

>
> I made this temporary workaround that does work but of course I must be
> screwing up somewhere else:
>
> while ($client = $sock->accept() || $client = $sock->accept()) {
>   # handle client here
> }

Since it appears that you want the loop to be infinite, why not just make
it explicitly infinite?

while (1) {
my $client=$sock->accept();
unless (defined $client) {
next if $! eq 'Whatever that error was';
die "Unexpected error $!";
}
#.....
}


> I hope someone can help or provide an example. I've included the client
> + server code below for those who are interrested in taking a p.

Looking through some old code I have, I see that I don't use a sig handler
at all.  I just put the "while (waitpid(-1,WNOHANG) > 0) {}" directly into
"accept" loop, as the first command after the accept.  I don't recall
exactly why I did that, but it may have been due to a problem like what you
see.  In this method, old forked servers stick around as zombies slightly
longer (until the next client connects), but I don't think that that is a
big deal.

>
> Thanks,
> Craig Manley

Xho

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

Report this thread to moderator Post Follow-up to this message
Old Post
xhoster@gmail.com
04-19-05 01:56 AM


Re: Need help with a simple UNIX sockets server based on IO::Socket::UNIX
"Craig Manley" <glideraerobatics@hotmail.com> wrote:
> Hi. I've tried to create a simple client + server that communicate
> through a unix socket.
>
> As with all socket servers, it has a loop where it waits for
> connections:
>
> while ($client = $sock->accept()) {
>   # handle client here
> }
>
> The problem is that $sock->accept() is returning undef on each
> alternate client connection with error "No child processes".

This is just a wild guess, but I think that what is happening is that
your $sock->accept call is being interupted by the SIGCHLD, and is not
getting automatically restarted once the sig handler finishes.

>
> I made this temporary workaround that does work but of course I must be
> screwing up somewhere else:
>
> while ($client = $sock->accept() || $client = $sock->accept()) {
>   # handle client here
> }

Since it appears that you want the loop to be infinite, why not just make
it explicitly infinite?

while (1) {
my $client=$sock->accept();
unless (defined $client) {
next if $! eq 'Whatever that error was';
die "Unexpected error $!";
}
#.....
}


> I hope someone can help or provide an example. I've included the client
> + server code below for those who are interrested in taking a p.

Looking through some old code I have, I see that I don't use a sig handler
at all.  I just put the "while (waitpid(-1,WNOHANG) > 0) {}" directly into
"accept" loop, as the first command after the accept.  I don't recall
exactly why I did that, but it may have been due to a problem like what you
see.  In this method, old forked servers stick around as zombies slightly
longer (until the next client connects), but I don't think that that is a
big deal.

>
> Thanks,
> Craig Manley

Xho

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

Report this thread to moderator Post Follow-up to this message
Old Post
xhoster@gmail.com
04-23-05 08:56 AM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

PERL Modules archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 07:09 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.