2

Running the following server and client scripts:

Server (updated):

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say' ;
use AnyEvent ;
use AnyEvent::Socket ;
use AnyEvent::Handle ;

tcp_server 'unix/', '/tmp/.mysocket', sub {
    my ( $fh, @args ) = @_ ;
    say "Received request" ;
    my $hdl = AnyEvent::Handle->new( fh => $fh ) ; 
    $hdl->push_read(
        line =>  sub {
            my ( $hdl, $line ) = @_ ;
            say "Received $line" ;
        }
    ) ;
}, sub {
    my ( $fh, @sock ) = @_ ;
    say "Bound to @sock" ;
} ;

AnyEvent->condvar->recv ;

exit ;  

Client (updated):

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say' ;
use AnyEvent ;
use AnyEvent::Socket ;
use AnyEvent::Handle ;

my $done = AnyEvent->condvar ;
tcp_connect "unix/", "/tmp/.mysocket", sub {
    my ( $fh ) = @_ or die "unable to connect: $!" ;
    say "Connected" ;
    my $hdl = AnyEvent::Handle->new( fh => $fh ) ;
    $hdl->push_write( "Hello world!\n" ) ;
    $done->send ;
}  ;

$done->recv ;
say $! ;

exit ;

the server receives and accepts the connection request but the client gets an "Illegal seek" error, skips the callback defined in tcp_connect and exits without sending the "Hello world" message to the server.

What am I doing wrong?

Update

Ok.. I figured out that due to the async nature of the AnyEvent module the client gets the "Illegal seek" because the script ends. Adding a condvar variable I solved that (non)problem, but the server still doesn't receives the message sent by client.

Hannibal
  • 445
  • 4
  • 13

1 Answers1

2

I am not sure what causes the "illegal seek error" yet, but I found something that at least works for now. The client needs to use a condition variable in the connection callback:

my $client_done = AnyEvent->condvar;
tcp_connect "unix/", "/tmp/.mysocket", sub {
    my ( $fh ) = @_ or die "unable to connect: $!" ;
    say "Connected" ;
    my $hdl = AnyEvent::Handle->new( fh => $fh ) ;
    $hdl->push_write( "Hello world!\n" ) ;
    $client_done->send;
};
$client_done->recv;
say "Done";

In addition, the server should not use a on_read callback but instead use push_read() method:

my $server_done = AnyEvent->condvar;
tcp_server 'unix/', '/tmp/.mysocket', sub {
    my ( $fh, @args ) = @_ ;
    say "Received request" ;
    my $hdl ;
    $hdl = AnyEvent::Handle->new(
        fh      => $fh,
        on_eof   => sub {
            say "server_eof";
            $server_done->send;
            undef $hdl;
        }
    );
    $hdl->push_read (
        line => sub {
            say "server got line <$_[1]>";
        }
    );
}, sub {
    my ( $fh, @sock ) = @_ ;
    say "Bound to @sock" ;
};
say "Waiting for server done..";
$server_done->recv;
Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
  • I figured out that due to the async nature of the AnyEvent module the client gets the "Illegal seek" because the script ends because of the missing condvar as you pointed out. I have updated my code while you were replying :-( Anyway: GREAT!!! Thanks for the working sample that solves my problem! – Hannibal Oct 16 '21 at 18:54