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.
CodePudding user response:
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;