为什么箭头键搞乱stdout?

时间:2015-11-30 15:55:53

标签: c multithreading bash terminal network-programming

我正在编写一个简单的客户端 - 用C语言实现网络编程的服务器程序。服务器可以使用多线程处理多个客户端。每个客户端都在一个单独的线程中提供服务。客户端使用两个线程:一个用于从stdin获取用户输入,另一个用于打印到stdout。

我用常规文本测试了程序,它运行得很好。但是,当我输入箭头键时,它表现得非常奇怪(左键= ^ [[D,右键= ^ [[C,向上键= ^ [[A,向下键= ^ [[B]。

例如,请参阅此输出: 这是我按顺序(在客户端)发送的输入:

>> test
I got your message
>> test1
I got your message
>> test2
I got your message
>> test3
I got your message

这是服务器中的(正确)输出:

Here is the message: test
Here is the message: test1
Here is the message: test2
Here is the message: test3

现在我输入随机箭头键(在输入test3之后):

>>^[[D^[[A^[[C^[[A^[[D^[[C^[[A^[[D^[[B^[[C^[[D^[[B^[[D^[[C^[[A^[[D^[[C^[[A^[[D^[[A^[[D^[[C^[[A
I got your message

但是,服务器什么都不打印(我假设字符被转义):

Here is the message: test
Here is the message: test1
Here is the message: test2
Here is the message: test3
Here is the message: 

Now, I start inputting normal text:

>> test4
I got your message
>> test5
I got your message
>> test6
I got your message
>> test7
I got your message
>> test8
I got your message
>> test9
I got your message
>> test10
I got your message

当我检查服务器的标准输出时,所有先前的打印输出都被覆盖:

Here is the message: test4
Here is the message: test5
Here is the message: test6
Here is the message: test7
Here is the message: test8
Here is the message: test9
Here is the message: test10

最重要的是,行为会随着我输入的箭头的随机击键而改变。有时,输入不会覆盖服务器的标准输出,但它会在stdout中插入输入。

我不确定为什么会这样,但是,如果有人想查看我的来源,我可以发布它。来源不长 - 客户端和服务器长约100行。

好的,我单独测试了每个键。

向下键和向上键似乎按行在stdout中移动文件指针。而左右键似乎什么都不做。

2 个答案:

答案 0 :(得分:0)

您将stdout(这是一个字节流)与将这些字节输入终端仿真器的结果混淆。如果你捕获你的服务器 stdout到文件中,您将能够使用十六进制编辑器(或hd命令)查看它,您将看到发送的实际字节数。

终端模拟器获取这些字节并将其转换为操作,从而使显示器显示某些内容。字节或字节序列可以显示为单个字素(可见符号)或解释为控制代码(移动光标,更改输出或背景颜色等),甚至只是忽略。

要了解如何解释这些字节,您可以查阅终端模拟器的文档(如果可以找到)或尝试XTerm documentation中的有用摘要(特定于xterm但是大多数现代终端仿真器都类似)或man 4 console_codes(特定于Linux控制台,但与大多数终端仿真器类似)。

答案 1 :(得分:0)

箭头键正在发送多字符ANSI转义序列。 BASH(和其他程序)使用像readline(或者curses)这样的库来将转义序列转换为光标移动/编辑。如果您不想使用这样的库,您可以将终端置于原始模式并读取和处理每个转义序列,并通过发送光标移动序列来移动光标,这是一个困难的过程。