I can't run the following because Windows doesn't provide SO_REUSEPORT
, but I'm extremely confident that the following does what you requested.
That said, I'm not sure it will help. From what I've read, SO_REUSEPORT
allows you to bind to an already active port, but you're not binding to any port.
use strict;
use warnings;
use AnyEvent qw( );
use AnyEvent::Handle qw( );
use AnyEvent::Impl::EV qw( );
use AnyEvent::Socket qw( tcp_connect );
use Socket qw( SOL_SOCKET SO_REUSEPORT );
sub transaction {
my ($host, $port) = @_;
tcp_connect($host, $port, sub {
my ($sock) = @_
or die "Can't connect: $!";
my $handle;
$handle = AnyEvent::Handle->new(
fh => $sock,
on_eof => sub {
$handle->destroy();
},
on_read => sub {
my ($handle) = @_;
print $handle->rbuf();
# This should continue to read until header +
# Content-Length bytes have been read instead
# of stopping after one read.
$handle->destroy();
},
);
$handle->push_write("GET / HTTP/1.1\r\nHost: $host\r\n\r\n");
$handle->push_shutdown(); # Done writing.
}, sub {
my ($sock) = @_;
setsockopt($sock, SOL_SOCKET, SO_REUSEPORT, 1)
or die $!;
return undef;
});
}
{
my $cv = AnyEvent->condvar();
my $t = AnyEvent->timer(after=>0.001, interval=>0.001, cb=> sub {
transaction("localhost", $ARGV[0] // die("usage"));
});
$cv->recv();
}
Server used for testing:
use strict;
use warnings;
use 5.010;
use IO::Socket::INET qw( );
use Socket qw( inet_ntoa );
my $serv = IO::Socket::INET->new(
Listen => 1,
);
say inet_ntoa($serv->sockaddr) . ":" . $serv->sockport;
while (my $client = $serv->accept()) {
say "Connection from ".inet_ntoa($client->peeraddr).":".$client->peerport;
while (<$client>) {
last if /^(?:\r?\n)?\z/;
}
say $client "HTTP/1.1 200 OK\r\n"
. "Content-Type: text/plain\r\n"
. "\r\n"
. "Hello\n";
say " done.";
}