簡體   English   中英

將終端設置為原始模式:僅在按下下一個鍵后才顯示字符

[英]Setting terminal to raw mode: Character is displayed only after next key pressed

我正在關注http://api.libssh.org/master/libssh_tutor_shell.html教程,該課程介紹了如何對基本SSH客戶端進行編程。

我不希望在(本地)終端中將ENTER鍵作為換行符回顯。 另外,我希望輸入可以在准備就緒時立即讀取並發送,而不要在按下ENTER之后才發送。

使用下面的代碼,我嘗試完成此操作。

然而,問題在於,在客戶終端中,每當按下一個鍵時,在下一次按下鍵后首先顯示該字符。 造成這種現象的原因是什么?

此函數確定是否已按下一個鍵:

int kbhit()
{
    struct timeval tv = {0L, 0L};
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(0, &fds);
    return select(1, &fds, NULL, NULL, &tv);
}

從服務器讀取數據/向服務器發送數據:

struct termios term_attr;
struct termios old_attr;

tcgetattr(STDIN_FILENO, &old_attr);
cfmakeraw(&term_attr);
tcsetattr(STDIN_FILENO, TCSANOW, &term_attr);

while (ssh_channel_is_open(channel) && !ssh_channel_is_eof(channel))
{
    nbytes = ssh_channel_read_nonblocking(channel, buff, sizeof(buff), 0);

    if (nbytes < 0)
    {
        return SSH_ERROR;
    }

    if (nbytes > 0)
    {
        nwritten = write(1, buff, nbytes);

        if (nwritten != nbytes)
        {
            return SSH_ERROR;
        }
    }

    if (!kbhit)
    {
        usleep(5000L);
        continue;
    }

    nbytes = read(0, buff, sizeof(buff));

    if (nbytes < 0)
    {
        return SSH_ERROR;
    }

    if (nbytes > 0)
    {
        nwritten = ssh_channel_write(channel, buff, nbytes);

        if (nwritten != nbytes)
        {
            return SSH_ERROR;
        }
    }
}

tcsetattr(STDIN_FILENO, TCSANOW, &old_attr);

您的程序將所有時間都花在了read功能上。 因此,直到ssh_channel_read_nonblocking后,它再也不會調用ssh_channel_read_nonblocking

流程如下:

  1. 我按了一個鍵。
  2. 您將該密鑰發送到另一側。
  3. 由於if (!kbhit)為true(因為kbhit不為NULL),我們繼續read
  4. 另一端在ssh通道上向我們發送回顯,但由於在stdin上的read被阻止,因此我們不會讀取它。
  5. 按下下一個鍵,我們循環,並調用ssh_channel_read_nonblocking ,獲取回顯,然后回顯它。

也許您應該調用kbhit函數,而不是測試函數指針是否為false。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM