AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Socket.pm view on Meta::CPAN
# print response header
print "HEADER\n$line\n\nBODY\n";
$handle->on_read (sub {
# print response body
print $_[0]->rbuf;
$_[0]->rbuf = "";
});
});
}, sub {
my ($fh) = @_;
# could call $fh->bind etc. here
15
};
Example: connect to a UNIX domain socket.
tcp_connect "unix/", "/tmp/.X11-unix/X0", sub {
...
}
=cut
sub tcp_connect($$$;$) {
my ($host, $port, $connect, $prepare) = @_;
# see http://cr.yp.to/docs/connect.html for some tricky aspects
# also http://advogato.org/article/672.html
my %state = ( fh => undef );
# name/service to type/sockaddr resolution
resolve_sockaddr $host, $port, 0, 0, undef, sub {
my @target = @_;
$state{next} = sub {
return unless exists $state{fh};
my $errno = $!;
my $target = shift @target
or return AE::postpone {
return unless exists $state{fh};
%state = ();
$! = $errno;
$connect->();
};
my ($domain, $type, $proto, $sockaddr) = @$target;
# socket creation
socket $state{fh}, $domain, $type, $proto
or return $state{next}();
AnyEvent::fh_unblock $state{fh};
my $timeout = $prepare && $prepare->($state{fh});
$timeout ||= 30 if AnyEvent::WIN32;
$state{to} = AE::timer $timeout, 0, sub {
$! = Errno::ETIMEDOUT;
$state{next}();
} if $timeout;
# now connect
if (
(connect $state{fh}, $sockaddr)
|| ($! == Errno::EINPROGRESS # POSIX
|| $! == Errno::EWOULDBLOCK
# WSAEINPROGRESS intentionally not checked - it means something else entirely
|| $! == AnyEvent::Util::WSAEINVAL # not convinced, but doesn't hurt
|| $! == AnyEvent::Util::WSAEWOULDBLOCK)
) {
$state{ww} = AE::io $state{fh}, 1, sub {
# we are connected, or maybe there was an error
if (my $sin = getpeername $state{fh}) {
my ($port, $host) = unpack_sockaddr $sin;
delete $state{ww}; delete $state{to};
my $guard = guard { %state = () };
$connect->(delete $state{fh}, format_address $host, $port, sub {
$guard->cancel;
$state{next}();
});
} else {
if ($! == Errno::ENOTCONN) {
# dummy read to fetch real error code if !cygwin
sysread $state{fh}, my $buf, 1;
# cygwin 1.5 continously reports "ready' but never delivers
# an error with getpeername or sysread.
# cygwin 1.7 only reports readyness *once*, but is otherwise
# the same, which is actually more broken.
# Work around both by using unportable SO_ERROR for cygwin.
$! = (unpack "l", getsockopt $state{fh}, Socket::SOL_SOCKET(), Socket::SO_ERROR()) || Errno::EAGAIN
if AnyEvent::CYGWIN && $! == Errno::EAGAIN;
}
return if $! == Errno::EAGAIN; # skip spurious wake-ups
delete $state{ww}; delete $state{to};
$state{next}();
}
};
} else {
$state{next}();
}
};
$! = Errno::ENXIO;
$state{next}();
};
defined wantarray && guard { %state = () }
}
=item $guard = tcp_server $host, $service, $accept_cb[, $prepare_cb]
( run in 0.816 second using v1.01-cache-2.11-cpan-3782747c604 )