libssh2: запись пакета: ошибка на сокете (или соединение закрыто)

0

Я следил за учебником, найденным по ссылке. Все работает нормально, я могу выполнять команды на удаленных хостах. Однако, когда я пытаюсь вызвать функцию ssh_channel_request_exec() при сеансе с Zhone MXK 198 (это сетевое устройство), я получаю следующую ошибку:

Writing packet: error on socket (or connection closed): Operation now in progress.

Однако я могу подключиться к этому устройству вручную (используя openssh). Я думаю, что эта ошибка имеет какое-то отношение к факту, что CLI на MXK немного отличается от обычного CLI, известного из Linux. Например, backspace интерпретируется как удаление, поэтому что-то не так с помощью сопоставления клавиш. Я предполагаю, что мне нужно изменить формат данных, которые отправляются в сокет. Или, может быть, я ошибаюсь? Можете ли вы дать мне несколько идей?

  • 0
    Похоже, что проблема вызвана тем, что основной сокет неожиданно находится в неблокированном режиме. Я никогда не имел дело с libssh, но в документации упоминаются как минимум ssh_set_blocking и ssh_channel_set_blocking . Вы можете попытаться выключить или включить его и просмотреть свой код на предмет отсутствия блокировки.
  • 0
    Я попытался включить режим блокировки для сеанса и канала, но это не помогло - все та же ошибка. Вот код: pastebin.com/AXq36P3e
Показать ещё 2 комментария
Теги:
ssh
libssh2

1 ответ

0
Лучший ответ

Я не думаю, что вы дошли до того, что ключевые коды были проблемой. Из сообщения, которое вы указали, я подозреваю, что вы вызвали функцию async, но рассматривали его как синхронизацию, вызывая ошибку, а не ожидая.

Предположим, что у нас есть следующий фрагмент кода:

n = recv(socket, buffer, sizeof buffer, 0);
if (n == -1) {
    err(1, "Error receiving data from socket");
}
<work with the n bytes received on buffer>

Это нормально для синхронного сокета в большинстве случаев¹, но если это асинхронная операция (вы передавали MSG_DONTWAIT на флаги или устанавливали O_NONBLOCK с помощью fcntl/setsockopt), вы должны ожидать, что он вернет -1 с EAGAIN качестве номера ошибки.

¹ В реальном приложении вы также должны обрабатывать EINTR (например, процесс получил сигнал).

В этом случае вы получаете EINPROGRESS, из которого мы можем собрать, что функция "failing", которая не была выполнена, - connect(). Посмотрите, что является возможной причиной ошибки сокета einprogress?

Страница справки connect (2) также очень подробно описывает эту ошибку:

EINPROGRESS
    The socket is nonblocking and the connection cannot be completed immediately.  
    It is possible to  select(2)  or  poll(2) for  completion  by  selecting the 
    socket for writing.  After select(2) indicates writability, use getsockopt(2) 
    to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() 
    completed  successfully  (SO_ERROR  is  zero)  or unsuccessfully (SO_ERROR is 
    one of the usual error codes listed here, explaining the reason for the failure).

Вы можете либо изменить libssh на блокировку с помощью ssh_set_blocking(), либо использовать select/poll в сокете с флагами ssh_get_poll_flags().

  • 0
    Когда я устанавливаю сеанс в неблокирующий режим с помощью ssh_set_blocking (session, 0), он не может соединиться (ssh_connect () не возвращает SSH_OK). И когда я устанавливаю его в режим блокировки с помощью ssh_set_blocking (session, 1), он возвращает ошибку, которую я описал выше при вызове функции ssh_channel_request_exec (). Я бы с удовольствием использовал выбор и опрос, но у меня совершенно нет опыта игры с сокетами, так что для меня это слишком сложно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню