gpt4 book ai didi

c++ - 将终端设置为原始模式 : Character is displayed only after next key pressed

转载 作者:太空宇宙 更新时间:2023-11-04 12:23:34 25 4
gpt4 key购买 nike

我正在学习教程 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

流程如下:

  1. 我敲了一个键。
  2. 您将该 key 发送给另一方。
  3. 由于 if (!kbhit) 为真(因为 kbhit 不为 NULL),我们继续读取
  4. 另一方在 ssh channel 上向我们发送回显,但我们不会读取它,因为我们在标准输入的 read 中被阻止。
  5. 您按下一个键,我们循环,然后调用 ssh_channel_read_nonblocking,获取回显,然后回显。

也许您应该调用 kbhit 函数而不是测试函数指针是否为假。

关于c++ - 将终端设置为原始模式 : Character is displayed only after next key pressed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45349133/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com