Я работаю с github.com/tarm/serial
для взаимодействия с некоторыми последовательными приборами.В процессе разработки я работаю с парой /dev/ttyp0
и /dev/ptyp0
, где мой процесс go подключается к одному, и я использую screen
для подключения к другому.Я написал функцию, которая в сочетании с serial.Config.ReadTimeout
читает до ReadTimeout
или получает заданную последовательность байтов.Эта функция:
func readToTermination(s serial.Port, termination []byte, rate time.Duration) []byte {
var out []byte
lterm := len(termination)
for {
buf := make([]byte, 128)
n, _ := s.Read(buf)
out = append(out, buf[:n]...)
l := len(out)
if l >= lterm {
if bytes.Compare(out[l-lterm:], termination) == 0 {
break
}
}
time.Sleep(rate)
}
return out
}
Это позволяет избежать сгорания циклов ЦП, ничего не делая с отладкой.Когда я тестирую с termination = []byte("\n")
и экраном, break
никогда не срабатывает, потому что он превращается в []byte{97, 11}
(два отдельных элемента, что-то вроде сброса экрана после каждого нажатия клавиши).С другой стороны, если я сделаю что-то вроде echo "foo" > /dev/ptyp0
, разрыв срабатывает правильно.Эхо неявно, похоже, отправляет \n
, или закрытие соединения делает это.Я вижу \r\n
для echo foo
и \r\n\r\n
для echo "foo\n"
.
Итак, мой вопрос:
(1), почему здесь разница в поведении?
(2) как мне получить поведение, которое я действительно испытываю, с возвратом каретки для прекращения?Возможно я должен использовать EOT вместо этого?Человек никогда не будет вводить это напрямую.