Describe the problem
On Windows, responses from a serial device occasionally arrive with exactly 1 byte missing at the head (e.g., IDO 06,F0,... → DO 06,F0,...). Same hardware with a C++ MFC implementation using direct Win32 calls (SetupComm + SetCommMask(EV_RXCHAR) + WaitCommEvent + drain-until-empty loop, MSDN-standard CommTimeouts) runs thousands of cycles without any byte loss. The Go library skips SetupComm and WaitCommEvent, and uses a non-standard CommTimeouts pattern (MAXDWORD, MAXDWORD, 0x7FFFFFFE — labeled "CH340 hack" in source). The hypothesis is that without event-driven drain, gaps between Read() calls allow the driver RX queue (default size, possibly small) to drop bytes under bursty traffic.
To reproduce
Connect to a serial device that emits short responses (~30 bytes) at ~200ms intervals (e.g., a polled status interface returning 8 hex pairs).
Send another short command via Write() immediately after each response.
Loop for several hundred cycles.
Observe: occasional 1-byte truncation at the start of an incoming response. Frequency ~1 per a few hundred cycles on RS-232 at 57600 baud.
// SERVER (controller emulator) — run on COM4
package main
import (
"bytes"
"log"
"time"
"go.bug.st/serial"
)
func main() {
p, err := serial.Open("COM4", &serial.Mode{BaudRate: 57600,
DataBits: 8, Parity: serial.NoParity, StopBits: serial.OneStopBit})
if err != nil { log.Fatal(err) }
defer p.Close()
p.SetReadTimeout(1 * time.Second)
buf := make([]byte, 4096)
var accum []byte
resp := []byte("IDI 0F,12,34,56,78,9A,BC,DE\r\n")
for {
n, err := p.Read(buf)
if err != nil { return }
if n == 0 { continue }
accum = append(accum, buf[:n]...)
for {
idx := bytes.Index(accum, []byte("\r\n"))
if idx < 0 { break }
accum = accum[idx+2:]
// 즉시 응답 (실제 controller 처럼 빠르게)
p.Write(resp)
}
}
}
Please double-check that you have reported each of the following
before submitting the issue.
Expected behavior
Bytes delivered by the driver to the application should not be silently dropped. The C++ Win32 pattern (SetupComm(handle, 4096, 4096) + SetCommMask(EV_RXCHAR) + WaitCommEvent + do { ReadFile } while (n > 0)) on identical hardware delivers all bytes intact for 1000+ cycles. Reading via this library should give equivalent reliability.
Operating system and version
Windows 10 (also reproducible on Windows 11). USB-Serial RS-232 adapter at 57600 8N1, 1m cable. go.bug.st/serial v1.6.4, Go 1.26.
Please describe your hardware setup
To reproduce
- Install com0com (https://com0com.sourceforge.net/) — creates virtual COM3↔COM4.
- Run server (provided below) on COM4 — echoes "IDI ..." responses.
- Run client (provided above) on COM3 — polls every 300ms.
- Wait several hundred cycles.
Note: byte loss is hardware-dependent. Virtual com0com driver may not
reproduce it exactly. On physical hardware (RS-232 + USB-Serial adapter +
real controller), it reproduces consistently at ~1 per 200-800 cycles.
The underlying concern is the code-level analysis below.
Additional context
No response
Issue checklist
Describe the problem
On Windows, responses from a serial device occasionally arrive with exactly 1 byte missing at the head (e.g., IDO 06,F0,... → DO 06,F0,...). Same hardware with a C++ MFC implementation using direct Win32 calls (SetupComm + SetCommMask(EV_RXCHAR) + WaitCommEvent + drain-until-empty loop, MSDN-standard CommTimeouts) runs thousands of cycles without any byte loss. The Go library skips SetupComm and WaitCommEvent, and uses a non-standard CommTimeouts pattern (MAXDWORD, MAXDWORD, 0x7FFFFFFE — labeled "CH340 hack" in source). The hypothesis is that without event-driven drain, gaps between Read() calls allow the driver RX queue (default size, possibly small) to drop bytes under bursty traffic.
To reproduce
Connect to a serial device that emits short responses (~30 bytes) at ~200ms intervals (e.g., a polled status interface returning 8 hex pairs).
Send another short command via Write() immediately after each response.
Loop for several hundred cycles.
Observe: occasional 1-byte truncation at the start of an incoming response. Frequency ~1 per a few hundred cycles on RS-232 at 57600 baud.
Please double-check that you have reported each of the following
before submitting the issue.
Expected behavior
Bytes delivered by the driver to the application should not be silently dropped. The C++ Win32 pattern (SetupComm(handle, 4096, 4096) + SetCommMask(EV_RXCHAR) + WaitCommEvent + do { ReadFile } while (n > 0)) on identical hardware delivers all bytes intact for 1000+ cycles. Reading via this library should give equivalent reliability.
Operating system and version
Windows 10 (also reproducible on Windows 11). USB-Serial RS-232 adapter at 57600 8N1, 1m cable. go.bug.st/serial v1.6.4, Go 1.26.
Please describe your hardware setup
To reproduce
Note: byte loss is hardware-dependent. Virtual com0com driver may not
reproduce it exactly. On physical hardware (RS-232 + USB-Serial adapter +
real controller), it reproduces consistently at ~1 per 200-800 cycles.
The underlying concern is the code-level analysis below.
Additional context
No response
Issue checklist