Глава 3: Открытие удаленного терминала
Вернуться к содержанию
|
||
Открытие удаленного терминалаМы уже упоминали, что отдельное соединение по SSH может быть разделено между несколькими "channels" (прим.перевод. т.е. каналами), которые могут использоваться для различных целей. В этой главе рассказывается о том, как открывать один из таких каналов и использовать для удаленного запуска интерпретатора команд (прим.перевод. в обиходе консоли или терминала). Открытие и закрытие каналаФункция ssh_channel_new() создает канал и возвращает переменную типа ssh_channel. После создания канала открывается сессия SSH путем вызова функции ssh_channel_open_session(). Когда надобность в канале отпадет, необходимо отправить EOF (прим.перевод. end-of-file - символ конца файла) путем вызова функции sh_channel_close(). Сам же канал следует удалять функцией ssh_channel_free(). Ниже приводится пример операции открытия и закрытия канала
Интерактивная и не интерактивная сессияК интерактивной относится сессия, если используется командный интерпретатор в котором пользователь вводит одну команду за другой. В то же время, к не интерактивной приравнивается запуск команд в фоновом режиме без управляющего терминала. Если планируется использовать интерактивную сессию, необходимо создать псеводотерминал на удаленной стороне, который обычно называют сокращенно "pty" от "pseudo-teletype"(прим.перевод. псевдо-телетайп). При этом удаленные процессы не видят разницы при работе с текст-ориентированным терминалом. Если необходимо, запрашиваем "pty" при помощи функции ssh_channel_request_pty(), а размерность псевдотерминала устанавливаем (в строках и столбцах) функцией ssh_channel_change_pty_size(). Вне зависимости от выбранного типа сессии (интерактивной или не интерактивной), следующим шагом запрашиваем командную оболочку при помощи функции ssh_channel_request_shell().
Отображение передаваемых данных удаленным компьютеромОбычно программе необходимо принимать все данные "отображаемые" pty, потому что существует необходимость в анализе, регистрации или отображение этих данных. ssh_channel_read() и ssh_channel_read_nonblocking() являются простым способом для чтения данных из канала. Пример ниже показывает как ждать данных от удаленной стороны с помощью ssh_channel_read():
В отличии от ssh_channel_read(), ssh_channel_read_nonblocking() никогда не ждет прихода данных от удаленного процесса и возвращается немедленно. Если ssh_channel_read_nonblocking() используется в цикле, необходимо использовать вместе с ней usleep(3). Иначе, использующий её процесс будет занимать все процессорное время (прим.перевод. в обиходе зацикливание), а компьютер, на котором он запущен, встанет. Передача пользовательского ввода удаленному компьютеруВвод пользователя передается на удаленную сторону с помощью функции ssh_channel_write(). Следующий пример показывает как комбинируется неблокирующее чтение канала SSH и ожидание ввода символов с клавиатуры. После локального ввода производится отправка на удаленный компьютер:
Конечно, данная реализация является скудным эмулятором терминала, так как нажатие клавиш не должно выполняться локально, а на удаленной стороне. Так же пользовательский ввод не должен дожидаться отправки нажатия клавиши "Enter", а отправлять нажатие каждой клавиши. Это может быть достигнуто за счет установки локального терминала в "raw" режим с помощью функции cfmakeraw(3), которая является стандартной функцией Linux (прим.перевод. из состава библиотеки GNU C (GLIBC) или её варианта EGLIBC), а на других системах её нужно определять: Если не используется локальный терминал, а нечто из окружение графического рабочего стола, решение данных проблем с "echo" будут иметь отличия.
Функции ssh_channel_read() и ssh_channel_read_nonblocking() являются простыми, но они не адаптированы к приему данных более чем из одного канала SSH или файлового дескриптора. Предыдущий пример показывал получение данных из стандартного ввода (клавиатуры) в тоже время как получение данных из канала SSH было сложным. Функции ssh_select() и ssh_channel_select() обеспечивают более элегантный способ ожидания прихода данных из нескольких источников ввода. Функции ssh_select() и ssh_channel_select() напоминают стандартную UNIX-функцию select(2). Идея состоит в том, чтобы ждать некоего события: входных данных для чтения, исходящих данных для блокировки или исключающего случая. Обе эти функции "пассивно ждут", таким образом их можно безопасно использовать в цикле бесчисленное количество раз, так как они не будут сжирать процессорное время и проводить к зависанию компьютера. Поэтому эти функции довольно часто используются в пользовательских приложениях оперирующих циклами. Ниже приводится пример функции, которая ожидает как прихода данных из SSH-канала, так и со стандартного ввода (клавиатуры): Если запускаемое удаленно приложение является графическим, можно перенаправлять протокол X11 на локальный компьютер. Для этого, первым что нужно сделать, дать право осуществлять соединения X11 с помощью ssh_channel_accept_x11(). Тогда можно создать туннель для протокола X11 с помощью функции ssh_channel_request_x11(). Следующий код производит инициализацию канала и открытие сессии интерпретатора команд, и параллельно обрабатывает X11-соединения: Не забудьте установить переменную окружения $DISPLAY на удаленной стороне или не пытайтесь использовать X11-туннель удаленным приложением: | ||
Вернуться к содержанию
|
||