CDDB
view release on metacpan or search on metacpan
lib/CDDB.pm view on Meta::CPAN
}
#------------------------------------------------------------------------------
# Disconnect from a cddbp server. This is needed sometimes when a
# server decides a session has performed enough requests.
sub disconnect {
my $self = shift;
if ($self->{handle}) {
$self->command('quit'); # quit
$self->response(); # wait for any response
delete $self->{handle}; # close the socket
}
else {
$self->debug_print( 0, '--- disconnect on unconnected handle' );
}
}
#------------------------------------------------------------------------------
# Connect to a cddbp server. Connecting and disconnecting are done
# transparently and are performed on the basis of need. Furthermore,
# this routine will cycle through servers until one connects or it has
# exhausted all its possibilities. Returns true if successful, or
# false if failed.
sub connect {
my $self = shift;
my $cddbp_host;
# Try to get our hostname yet again, in case it failed during the
# constructor call.
unless (defined $self->{hostname}) {
$self->{hostname} = &hostname() or croak "can't get hostname: $!";
}
# The handshake loop tries to complete an entire connection
# negociation. It loops until success, or until HOST returns
# because all the hosts have failed us.
HANDSHAKE: while ('true') {
# Loop through the CDDB protocol hosts list up to twice in order
# to find a server that will respond. This implements a 2x retry.
HOST: for (1..(@cddbp_hosts * 2)) {
# Hard disconnect here to prevent recursion.
delete $self->{handle};
($self->{host}, $self->{port}) = @{$cddbp_hosts[$cddbp_host_selector]};
# Assign the host we selected, and attempt a connection.
$self->debug_print(
0,
"=== connecting to $self->{host} port $self->{port}"
);
$self->{handle} = new IO::Socket::INET(
PeerAddr => $self->{host},
PeerPort => $self->{port},
Proto => 'tcp',
Timeout => 30,
);
# The host did not answer. Clean up after the failed attempt
# and cycle to the next host.
unless (defined $self->{handle}) {
$self->debug_print(
0,
"--- error connecting to $self->{host} port $self->{port}: $!"
);
delete $self->{handle};
$self->{host} = $self->{port} = '';
# Try the next host in the list. Wrap if necessary.
$cddbp_host_selector = 0 if ++$cddbp_host_selector > @cddbp_hosts;
next HOST;
}
# The host accepted our connection. We'll push it back on the
# list of known cddbp hosts so it can be tried later. And we're
# done with the host list cycle for now.
$self->debug_print(
0,
"+++ successfully connected to $self->{host} port $self->{port}"
);
last HOST;
}
# Tried the whole list twice without success? Time to give up.
unless (defined $self->{handle}) {
$self->debug_print( 0, "--- all cddbp servers failed to answer" );
warn "No cddb protocol servers answer. Is your network OK?\n"
unless $self->{debug};
return;
}
# Turn off buffering on the socket handle.
select((select($self->{handle}), $|=1)[0]);
# Get the server's banner message. Try reconnecting if it's bad.
my $code = $self->response();
if ($code != 2) {
$self->debug_print(
0, "--- bad cddbp response: ",
$self->code(), ' ', $self->text()
);
next HANDSHAKE;
}
# Say hello, and wait for a response.
$self->command(
'cddb hello',
$self->{login}, $self->{hostname},
$self->{libname}, $self->{libver}
);
$code = $self->response();
if ($code == 4) {
$self->debug_print(
( run in 2.162 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )