Я следил за учебником, найденным по ссылке. Все работает нормально, я могу выполнять команды на удаленных хостах. Однако, когда я пытаюсь вызвать функцию 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 интерпретируется как удаление, поэтому что-то не так с помощью сопоставления клавиш. Я предполагаю, что мне нужно изменить формат данных, которые отправляются в сокет. Или, может быть, я ошибаюсь? Можете ли вы дать мне несколько идей?
Я не думаю, что вы дошли до того, что ключевые коды были проблемой. Из сообщения, которое вы указали, я подозреваю, что вы вызвали функцию 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().