C++ 将终端设置为原始模式:仅在按下下一个键后显示字符
我正在学习如何编写基本SSH客户端的教程 我不希望ENTER键作为换行符在(本地)终端中回显。此外,我希望输入被读取和发送,一旦它准备好,而不是在输入已按下 使用下面的代码,我试图实现这一点 然而,问题是,在客户端终端中,每当按下一个键时,该字符在下一次按键后首先显示。这种行为的原因是什么 此功能确定是否已按下某个键:C++ 将终端设置为原始模式:仅在按下下一个键后显示字符,c++,c,linux,ssh,C++,C,Linux,Ssh,我正在学习如何编写基本SSH客户端的教程 我不希望ENTER键作为换行符在(本地)终端中回显。此外,我希望输入被读取和发送,一旦它准备好,而不是在输入已按下 使用下面的代码,我试图实现这一点 然而,问题是,在客户端终端中,每当按下一个键时,该字符在下一次按键后首先显示。这种行为的原因是什么 此功能确定是否已按下某个键: int kbhit() { struct timeval tv = {0L, 0L}; fd_set fds; FD_ZERO(&fds);
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);
struct termios term\u attr;
结构术语旧属性;
tcgetattr(标准文件号和旧文件号);
cfmakeraw(和术语属性);
tcsetattr(标准文件号、TCSANOW和术语属性);
而(ssh_通道是开放的(通道)&!ssh_通道是开放的(通道))
{
nbytes=ssh\u channel\u read\u nonblocking(channel,buff,sizeof(buff),0);
如果(n字节<0)
{
返回SSH_错误;
}
如果(n字节>0)
{
nwrited=write(1,buff,n字节);
如果(nwrited!=n字节)
{
返回SSH_错误;
}
}
如果(!kbhit)
{
usleep(5000L);
继续;
}
n字节=读取(0,buff,sizeof(buff));
如果(n字节<0)
{
返回SSH_错误;
}
如果(n字节>0)
{
nwrited=ssh\u channel\u write(channel,buff,n字节);
如果(nwrited!=n字节)
{
返回SSH_错误;
}
}
}
tcsetattr(标准文件号、TCSANOW和旧属性);
您的程序将所有时间都阻塞在读取功能中。因此,它永远不会调用ssh\u channel\u read\u nonblocking
,直到按下一个键
以下是流程:
我按了一个键
你把钥匙送到另一边去
既然如果(!kbhit)
为真(因为kbhit
不为空),我们就转到读取
另一方通过ssh通道向我们发送回显,但我们不会读取它,因为我们在stdin上的read
中被阻塞
点击下一个键,我们循环,调用ssh\u channel\u read\u nonblocking
,获取回音,然后回音
也许您应该调用kbhit
函数,而不是测试函数指针是否为false。您的程序将其所有时间都阻塞在read
函数中。因此,它永远不会调用ssh\u channel\u read\u nonblocking
,直到按下一个键
以下是流程:
我按了一个键
你把钥匙送到另一边去
既然如果(!kbhit)
为真(因为kbhit
不为空),我们就转到读取
另一方通过ssh通道向我们发送回显,但我们不会读取它,因为我们在stdin上的read
中被阻塞
点击下一个键,我们循环,调用ssh\u channel\u read\u nonblocking
,获取回音,然后回音
也许您应该调用kbhit
函数,而不是测试函数指针是否为false