I am writing a Chatbot::Eliza local server on RH Linux 6.2. It will allow other processes to connect to a UNIX domain socket and converse with an Eliza instance. Something like /dev/eliza. I'll have to multithread it later.

My problem is that the server hangs when reading from the socket the first time. Do I need to put a special terminator on the string when writing to the socket?

Here's my basic approach:

$EOL = "\015\012";

client:
print SOCKET "$text$EOL";

server:
print STDOUT "Server about to read\n";
$input = <SOCKET>;
print STDOUT "Server read\n";
sample output:
prompt# Liza_client.pl

Socket created: /tmp/eliza_socket
Server socket bound
Server Listening
Connection accepted
Server about to read
How are you, Eliza?
send: nobody:How are you, Eliza?


Note: And here's the actual code It seems strange for the client to fork the server, but the client is just test code.
#! /usr/bin/perl -w
#Liza_client.pl
#This is just test code.

use strict;
use Socket;
use Carp;
my $EOL = "\015\012"; #Shouln't need a special terminator, but it doesn't hurt.

my ($input, $output, $msg);
my $child_pid = 0;

if ($child_pid = fork){
    print STDOUT "\nForked: $child_pid\n";
}
else{
    exec 'Liza_server.pl';

}

#sleep 10; #allow server some setup time.  More robust solution later.

my $TEMP_FILE = '/tmp/eliza_socket';

socket(SOCK, PF_UNIX, SOCK_STREAM, 0)  || die "Socket: $!";
connect(SOCK, sockaddr_un($TEMP_FILE)) || die "connect: $!";

while (1){
    $input = <>;
    $msg ="nobody:$input$EOL";
    print SOCK $msg;
    print STDOUT "send: $msg";
    $output = <SOCK>;
    print STDOUT "recieve: $output";
}

exit "Empty input: $input";


#! /usr/bin/perl -w
#Liza_server.pl
#Note to self: modify to run in taint mode.


use strict;
use Socket;
use Carp;
use Chatbot::Eliza;

my $EOL = "\015\012";  #We shouldn't need a special terminator, but here it is.
my $TEMP_FILE = '/tmp/eliza_socket';
my $uaddr = sockaddr_un($TEMP_FILE);
my $proto = getprotobyname('tcp');
my $input = "";
my $name = "none";
my $msg = "";

#first set up a socket

socket(Server, PF_UNIX, SOCK_STREAM, 0)  || die "socket failed: $!";
unlink($TEMP_FILE);
print STDOUT "Socket created: $TEMP_FILE\n";
bind(Server, $uaddr)                     || die "bind failed: $!";
print STDOUT "Server socket bound\n";
listen(Server, SOMAXCONN)                || die "list failed: $!";

print STDOUT "Server Listening\n";
accept(Client, Server) || die "accept failed: $!";
print STDOUT "Connection accepted\n";


#Now create an instance of Eliza 
my $bot = new Chatbot::Eliza {
    name       => 'localhost =-)', 
    scriptfile => 'script.txt',
    debug      => 0,
    prompts_on => 0,
    memory_on  => 1,
};
srand( time ^ ($$ + ($$ << 15)) );

#Listen and talk alternately.
#The looping condition will be changed when the thing actually works.
while (1){
    print STDOUT "Server about to read\n";

#This is where we hang:
    $input = <Client>;
    print STDOUT "Server read\n"; #never reached
    ($name, $msg) = split /:/o, $input, 2;
    print STDOUT "$name -> $msg";
    print Client $bot->transform($msg),$EOL;
}

exit "Closed Socket: $TEMP_FILE";

In reply to perlipc: UNIX domain socket read hangs. by karlm

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.