0

私のアプリはlibssh2を使用してSSH経由で通信し、通常は正常に動作します。私が抱えている問題の1つは、リモートホストが予期せず停止した場合です。この場合のリモートホストは、いつでも電力を失う可能性のある組み込みデバイスであるため、これは珍しいことではありません。

その場合、私のアプリはリモートコンピューターがpingへの応答を停止したことを検出し、次のようにSSH接続のローカルエンドを切断します。

void SSHSession :: CleanupSession()
{
   if (_uploadFileChannel)
   {
      libssh2_channel_free(_uploadFileChannel);
      _uploadFileChannel = NULL;
   }

   if (_sendCommandsChannel)
   {
      libssh2_channel_free(_sendCommandsChannel);
      _sendCommandsChannel = NULL;
   }

   if (_session)
   {
      libssh2_session_disconnect(_session, "bye bye");
      libssh2_session_free(_session);
      _session = NULL;
   }
}

非常に簡単ですが、問題は、libssh2_channel_free()呼び出しが、リモートエンドが「I'mgoing away now」メッセージに応答するのを長時間ブロックする可能性があることです。これは、電源がオフになっているため、決して実行されません...しかし、その間、私のアプリはフリーズします(クリーンアップルーチンでブロックされます)。これは良くありません。

これを回避する方法(libssh2をハッキングする以外)はありますか?ローカルSSHデータ構造を破棄し、この破棄中にブロックしないようにしたいと思います。(SSHセッションメモリを単にリークするか、別のスレッドに委任することができると思いますが、それらは適切な解決策ではなく、醜いハックのようです)

4

2 に答える 2

0

cbtype の LIBSSH2_CALLBACK_RECV で libssh2_session_callback_set を使用してソケットからデータを読み取るコールバック関数を設定することにより、ノンブロッキング モードに設定し、ソケットからのデータ読み取りを制御します。

void *libssh2_session_callback_set(LIBSSH2_SESSION *session, int cbtype, void *callback);

エラー ENOTCONN が原因でソケットからデータを読み取れない場合は、リモート エンドがソケットを閉じたか、接続に失敗したことを意味します。コールバック関数で -ENOTCONN を返します。

于 2013-11-20T04:27:15.653 に答える
0

libssh2_session_disconnect_ex私は libssh2 の経験はありませんが、別の切断理由を使用することで、libssh2 から別の動作を取得できる可能性がありますSSH_DISCONNECT_CONNECTION_LOST

libssh2_session_disconnectlibssh2_session_disconnect_exreason で使用するのと同じSSH_DISCONNECT_BY_APPLICATIONです。接続が失われていることを libssh2 が認識している場合は、相手側との通信を試みない可能性があります。

http://libssh2.sourceforge.net/doc/#libssh2sessiondisconnectex

http://libssh2.sourceforge.net/doc/#sshdisconnectcodes

于 2012-10-19T20:35:18.463 に答える