|
|
>
> I am working with UNIX Sockets and have some questions that I
> cant seem to find answers to on the web.
>
> 1: Are UNIX sockets bi-directional?
>
> 2: If so, what is the proper way to 'setup' the connection?
> (will post what I have below)
>
> 3: Do UNIX sockets have less overhead than INET sockets?
>
> Here is what I have for the OO connections:
>
> Server:
>
> my $server = IO::Socket::UNIX->new(Local => "/tmp/mysock",
> Type => SOCK_DGRAM,
> Listen => 5 )
> or die $@;
>
> Client:
>
> my $client = IO::Socket::UNIX->new (
> Type => SOCK_DGRAM,
> Peer => "/tmp/mysock",
> )
> or die $@;
>
> Right now, I am able to send information from the client to
> the server, but not the other way around. When I try this, I
> get:send:
>
> Cannot determine peer address at server.pl line 21
>
> Here are lines 17-22:
>
> if($text ne 'exit')
> {
> print "\nReceived message '", $text,"'\n";
> my $send = "I got: $text\n";
> $server->send($send,128); # <------- Line 21
> }
>
> I have tried multiple things with the creation of the socket,
> but cant get the right combination. I am beginning to think
> that UNIX sockets are not bi-directional, but I hope someone
> proves me wrong.
>
> If more information is needed, let me know.
>
> Thanks for the help,
>
> Dave Kettmann
> NetLogic
> 636-561-0680
>
Hi Dave
I pasted some example code I have played with a while ago and it does work.
I can't rember which perldoc or perl book I got it from.
#### SERVER
use IO::Socket;
use POSIX ":sys_wait_h"; # (for WNOHANG)
# example using unix domain socks
# once the file is created as a socket, any client can
# interact with it
my $sockname = "/tmp/unixsockd.sock";
start_daemon();
sub start_daemon {
my $pid;
if ($pid = fork()) {
# wait for child proc to die and do a non blocking wait for pending
zombies
waitpid($pid, 0);
} else {
if ($pid = fork()) { exit; }
$0 = "unixsockd: accepting connections on $sockname";
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,
) or die "$0: error starting daemon on '$sockname': $@\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() ) {
# fork yet another process to prevent buffer deadlock. one proc
writes to
# the sock, the other reads the deamons response
my $pid = fork(); die "Cannot fork\n" unless defined $pid;
if ($pid) { # parent
close $client; # no use to parent
next; # be ready for another client
}
# child
close $sock; # no use to child
process_requests($client);
exit; # terminate child
}
}
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
last if $line =~ /^\s$/; # 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;
}
## CLIENT
use IO::Socket;
my $sockname = "/tmp/unixsockd.sock";
my $client = IO::Socket::UNIX->new(
Peer => $sockname,
Type => SOCK_STREAM,
Timeout => 5,
) or die "$0: error connecting to '$sockname': $@\n";
my $pid = fork(); die "Cannot fork\n" unless defined $pid;
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);
}
}
--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.296 / Virus Database: 265.6.7 - Release Date: 12/30/2004
|
|