行缓冲发生在哪里?在哪个流上?
Where is the line buffering occuring? On which stream?
我正在通过蓝牙在我的 smartphone 和 Raspberry Pi 之间传输字节。 Pi 运行 raspbian 并在其 GPIO 头上附加了一个蓝牙串口。在 smartphone 上,我使用各种 android 蓝牙控制台应用程序。
要在 Pi 中查看来自 phone 的数据,在我使用的终端上:
socat /dev/ttyAMA0 -
这工作正常,字符双向流动,一切正常。
但是 - 当我通过蓝牙从 phone 应用程序向 Pi 发送一个字符串时,只有在换行之后我才能在 Pi 终端上看到该字符串。 Pi->phone也是如此。所以行缓冲正在进行中。
使用示波器我可以看到我从蓝牙应用程序发送的每个字符都会产生 RS232 数据,因此在 phone 的输出路径上没有缓冲。缓冲在 Pi 的某个地方,换行符正在刷新它。
谁能描述一下这是哪里? (我熟悉 none/line/block 缓冲方案 - 只是不 where (我认为))
他
富有
--- 更多详情 ---
因此,为了解决我 Raspberry Pi 上本地终端的问题,我编写了最小的 java 应用程序,以使用 [=11] 读取来自 /dev/ttyAMA0
的字符的紧密循环=].从字面上等待一个字节,将其打印到控制台(使用 println()
)然后再次等待 read()
。
在通过蓝牙发送 0x0A 之前,我无法读取任何字符,此时所有先前缓冲的字符都会被输出。
这使 socat
脱离了循环,并且不需要在那里关闭行缓冲。
行缓冲似乎仍在运行 - 但它在哪里?
富有
来自 socat 的手册页:
" ... when data is available on one side and can be written to the
other side, socat reads it, performs newline character conversions if
required, and writes the data to the write file descriptor of the
other stream, then continues waiting for more data in both
directions."
我猜 socat 写入 stdout 是行缓冲的,因此您只会在换行符之后在终端上看到该行.
我没用过socat,不过好像see/set文件描述符有几个选项,比如CW-D
和CWFD:<fdnum>
,参考man page .我会尝试将其更改为 stderr,看看会发生什么。
好吧,我终于解决了我的问题,足够深入,我可以继续我原来的发展道路。
我的解决办法是发出这个 TTY 设置:
stty -F /dev/ttyAMA0 raw
其中 raw
是其他选项的合并 - 参见 http://linux.die.net/man/1/stty
组合选项很多,但最明显的是 min 1
。
所以现在当我使用蓝牙控制台通过蓝牙从 phone 发送字符时,我的 Java 程序 运行ning 中实时显示字符 运行ning Raspberry Pi.
我的 java 从 uart-connected 蓝牙东西读取的程序正在使用 jSSC
库。仅此一项对线路缓冲没有帮助。我必须先 运行 stty ... raw
然后 运行 我自己的应用程序。
我的 Java 程序中的示例:
readBytes() read 1
char 'h value 104
End of readBytes()
readBytes() read 1
char 'e value 101
End of readBytes()
readBytes() read 3
char 'l value 108
char 'l value 108
char 'o value 111
End of readBytes()
readBytes() read 1
char '
value 10
End of readBytes()
最后会看到LF。所有其他 "hello" 在发送时被接收,而不是与 LF 一起在一个 readBytes() 中接收。
希望这对某人有所帮助!我不明白为什么这对 Pi 开发人员来说不是一个更常见的问题!
我正在通过蓝牙在我的 smartphone 和 Raspberry Pi 之间传输字节。 Pi 运行 raspbian 并在其 GPIO 头上附加了一个蓝牙串口。在 smartphone 上,我使用各种 android 蓝牙控制台应用程序。
要在 Pi 中查看来自 phone 的数据,在我使用的终端上:
socat /dev/ttyAMA0 -
这工作正常,字符双向流动,一切正常。
但是 - 当我通过蓝牙从 phone 应用程序向 Pi 发送一个字符串时,只有在换行之后我才能在 Pi 终端上看到该字符串。 Pi->phone也是如此。所以行缓冲正在进行中。
使用示波器我可以看到我从蓝牙应用程序发送的每个字符都会产生 RS232 数据,因此在 phone 的输出路径上没有缓冲。缓冲在 Pi 的某个地方,换行符正在刷新它。
谁能描述一下这是哪里? (我熟悉 none/line/block 缓冲方案 - 只是不 where (我认为))
他 富有
--- 更多详情 ---
因此,为了解决我 Raspberry Pi 上本地终端的问题,我编写了最小的 java 应用程序,以使用 [=11] 读取来自 /dev/ttyAMA0
的字符的紧密循环=].从字面上等待一个字节,将其打印到控制台(使用 println()
)然后再次等待 read()
。
在通过蓝牙发送 0x0A 之前,我无法读取任何字符,此时所有先前缓冲的字符都会被输出。
这使 socat
脱离了循环,并且不需要在那里关闭行缓冲。
行缓冲似乎仍在运行 - 但它在哪里?
富有
来自 socat 的手册页:
" ... when data is available on one side and can be written to the other side, socat reads it, performs newline character conversions if required, and writes the data to the write file descriptor of the other stream, then continues waiting for more data in both directions."
我猜 socat 写入 stdout 是行缓冲的,因此您只会在换行符之后在终端上看到该行.
我没用过socat,不过好像see/set文件描述符有几个选项,比如CW-D
和CWFD:<fdnum>
,参考man page .我会尝试将其更改为 stderr,看看会发生什么。
好吧,我终于解决了我的问题,足够深入,我可以继续我原来的发展道路。
我的解决办法是发出这个 TTY 设置:
stty -F /dev/ttyAMA0 raw
其中 raw
是其他选项的合并 - 参见 http://linux.die.net/man/1/stty
组合选项很多,但最明显的是 min 1
。
所以现在当我使用蓝牙控制台通过蓝牙从 phone 发送字符时,我的 Java 程序 运行ning 中实时显示字符 运行ning Raspberry Pi.
我的 java 从 uart-connected 蓝牙东西读取的程序正在使用 jSSC
库。仅此一项对线路缓冲没有帮助。我必须先 运行 stty ... raw
然后 运行 我自己的应用程序。
我的 Java 程序中的示例:
readBytes() read 1
char 'h value 104
End of readBytes()
readBytes() read 1
char 'e value 101
End of readBytes()
readBytes() read 3
char 'l value 108
char 'l value 108
char 'o value 111
End of readBytes()
readBytes() read 1
char '
value 10
End of readBytes()
最后会看到LF。所有其他 "hello" 在发送时被接收,而不是与 LF 一起在一个 readBytes() 中接收。
希望这对某人有所帮助!我不明白为什么这对 Pi 开发人员来说不是一个更常见的问题!