0

我的应用程序使用 libssh2 通过 SSH 进行通信,并且通常工作正常。我遇到的一个问题是远程主机意外死机——在这种情况下,远程主机是一个嵌入式设备,随时可能断电,所以这种情况并不少见。

发生这种情况时,我的应用程序检测到远程计算机已停止响应 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() 调用可能会阻塞很长时间,以等待远程端响应“我现在要走了”消息,因为它已关闭电源,所以它永远不会这样做......但与此同时,我的应用程序被冻结(在清理例程中被阻止),这不好。

有什么办法(除了破解 libssh2)可以避免这种情况吗?我只想拆除本地 SSH 数据结构,并且在拆除过程中从不阻塞。(我想我可以简单地泄漏 SSH 会话内存,或者将其委托给不同的线程,但这些看起来像丑陋的黑客而不是正确的解决方案)

4

2 回答 2

0

Set to non-blocking mode and take the control of reading data from the socket to your hand by setting callback function to read data from the soket using libssh2_session_callback_set with LIBSSH2_CALLBACK_RECV for cbtype

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

If you can't read data from the socket due to error ENOTCONN that means remote end has closed the socket or connection failed, then return -ENOTCONN in your callback function

于 2013-11-20T04:27:15.653 回答
0

我没有使用 libssh2 的经验,但也许我们可以通过使用libssh2_session_disconnect_ex和不同的断开原因从 libssh2 中获得不同的行为:SSH_DISCONNECT_CONNECTION_LOST.

libssh2_session_disconnect相当于使用libssh2_session_disconnect_exwith the reason SSH_DISCONNECT_BY_APPLICATION。如果 libssh2 知道连接丢失,也许它不会尝试与对方交谈。

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

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

于 2012-10-19T20:35:18.463 回答