J'appelle :: connect() sur un port d'application spéciale dans mon application et il fonctionne très bien en général, cependant, entre deux machines particulières, de l'un à l'autre, il échoue avec EHOSTUNREACH qui signifie « Pas de route pour accueillir. "Pourquoi est-ce que :: connect() retourne EHOSTUNREACH quand ssh fonctionne correctement?
Si je peux ssh sur le port 22 sans problème, ce qui pourrait se passer ici que :: connect() échoue toujours pour cette paire de machine particulière?
ssh Exécution des rendements en mode verbose:
[localMachine ~] ssh -v -p 22 remoteMachine
OpenSSH_3.9p1, OpenSSL 0.9.7a Feb 19 2003
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to remoteMachine [10.34.49.107] port 22.
debug1: Connection established.
debug1: identity file /home/WilliamKF/.ssh/identity type -1
debug1: identity file /home/WilliamKF/.ssh/id_rsa type 1
debug1: identity file /home/WilliamKF/.ssh/id_dsa type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_4.3
debug1: match: OpenSSH_4.3 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_3.9p1
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-cbc hmac-md5 none
debug1: kex: client->server aes128-cbc hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'remoteMachine' is known and matches the RSA host key.
debug1: Found key in /home/WilliamKF/.ssh/known_hosts:47
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-with-mic,password
debug1: Next authentication method: gssapi-with-mic
debug1: Authentications that can continue: publickey,gssapi-with-mic,password
debug1: Authentications that can continue: publickey,gssapi-with-mic,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/WilliamKF/.ssh/identity
debug1: Offering public key: /home/WilliamKF/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 149
debug1: read PEM private key done: type RSA
debug1: Authentication succeeded (publickey).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
est ici la fonction du côté client:
void // virtual
Sender::connectTCP()
{
// First build the feedback channel's socket & make it reuseable
// so we don't get the nasty message.
if (0 > (setFbSocket(socket(AF_INET, SOCK_STREAM, 0)))) {
THROW_ERR("failed to create the command socket: ");
}
setSocketOptions();
// Build the localIp address and bind it to the feedback socket.
// Although it's not traditional for a client to bind the sending socket
// to a the local address, we do it to prevent connect() from using an
// ephemeral port which (our site's firewall may block). Also build the
// remoteIp address.
buildAddr(getTCPcommandLocalAddr(), getLocalHost().c_str(),
getLocFbPort());
deepBind(getFbSocket(), getTCPcommandLocalAddr());
buildAddr(getTCPcommandRemoteAddr(), getRemoteHost().c_str(),
getRemFbPort());
// Connect to the receiver at the remote addr. Make multiple attempts
// when we get a connection refused errno (ECONNREFUSED). ECONNREFUSED
// means no one is listening at the other end ... which my be the result
// of a race condition (i.e., we're calling connect before the server has
// gotten to listen.)
const int timeoutMinutes = 5;
const int timeoutSeconds = timeoutMinutes * 60;
int conCount = timeoutSeconds;
while ((conCount > 0) &&
(0 > ::connect(getFbSocket(),
(sockaddr*)&getTCPcommandRemoteAddr(),
sizeof(sockaddr)))) {
switch (errno) {
case ECONNREFUSED: {
::sleep(1);
--conCount;
// Warn every 15 seconds, but don't warn at 5 minutes exactly.
if ((conCount % 15) == 0 && conCount) {
clog << "Warning: The server connection"
<< " has been refused for "
<< timeFromSeconds(timeoutSeconds - conCount)
<< ", will continue to retry for up to "
<< timeoutMinutes << " minutes.\n"
<< "Perhaps ports " << getRemFbPort() << " and "
<< getRemDataPort()
<<
" are not being routed properly to the server or alternatively "
"perhaps nothing on the server is listening to those ports?\n";
}
continue;
}
case EHOSTUNREACH: {
clog << "Error: Command connect failed: No route to host '"
<< getRemoteHost() << "'." << endl;
throw;
}
default: {
clog << "Error: Command connect failed: "
<< strerror(errno) << endl;
throw;
}
}
}
if (conCount == 0) {
clog << "Error: Command connect"
<< " continually refused after retrying for " << timeoutMinutes
<< " minutes: "
<< strerror(errno) << endl;
throw;
}
setCmdBlocking();
setDataBlocking();
setFbIsConn(true);
clog << "Application has connected to "
<< getRemoteHost() << ":" << getRemFbPort() << endl;
}
-t-il fonctionner pour d'autres machines? Vous avez un code à poster? –
Oui, cela fonctionne pour toutes les autres machines. – WilliamKF