为什么我在 Windows COM 端口上的串行读取限制为 8192 字节?

Why is my serial read on Windows COM port limited to 8192 bytes?

我正在尝试从 windows 中的 COM 端口读取 20100 个字节。数据被截断为 8192 字节。是什么赋予了?当我使用 TeraTerm 时,没有截断。我的同步调用是:

CreateFile(dev, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

和(非重叠只读的代码片段)

DWORD dwEventMask, dwIncommingReadSize;
int dwSize=0;
char szBuf[10];
if(!SetCommMask((void *) fd, EV_RXCHAR)) {THIS_RTN_ERROR}

do  {
        if(ReadFile((void *) fd, szBuf, 1, &dwIncommingReadSize, NULL) != 0) {
            if(dwIncommingReadSize > 0) {
                for (k=0; k<dwIncommingReadSize; k++) {
                  *(line_buf+dwSize+k) = szBuf[k];
                }
                dwSize += dwIncommingReadSize;
            }
        }
        else {THIS_RTN_ERROR;}
    } while(dwIncommingReadSize > 0);
k = dwSize;
return(k);

这在 WriteFile 之后立即发生。我反复调用此代码,直到获得所有数据 - 但我只获得 8192 字节。

您是否明确指定 8192 作为 SetupComm 函数中的 dwInQueue 参数,或者设备驱动程序默认值为 8192?

如何指定 SetupComm 所需的缓冲区大小?

SetupComm function

Initializes the communications parameters for a specified communications device.
Syntax C++

BOOL SetupComm(  
  HANDLE hFile,  
  DWORD  dwInQueue,  
  DWORD  dwOutQueue  
);

Parameters
hFile
A handle to the communications device. The CreateFile function returns this handle.

dwInQueue
The recommended size of the device's internal input buffer, in bytes.

dwOutQueue
The recommended size of the device's internal output buffer, in bytes.

对于.NET SerialPort,默认值为4096,最多可以指定2147483647。 SerialPort.ReadBufferSize Property

Gets or sets the size of the SerialPort input buffer.
C#

[System.ComponentModel.Browsable(true)]  
public int ReadBufferSize { get; set; }  

Property Value
Int32
The buffer size, in bytes. The default value is 4096; the maximum value is that of a positive int, or 2147483647.

这与其说是回答,不如说是评论。根据公认的答案,增加缓冲区大小将在 99.9% 的时间内解决您的问题。

但串行接口(如套接字)只是一个字节流。所以总是要处理两个对立的问题:

  • 部分消息
  • 多条消息

更糟糕的是,您可能会收到一条完整的消息,然后是截断的消息。

在 Unix 和 Windows 中,处理此问题的标准方法是使用 select。例如,参见 https://beej.us/guide/bgnet/.

生成的代码不长,但你需要知道你想要它做什么。


编辑:在Windows上,select仅适用于套接字。也许 Batch-File: Receive Data from the Serial-Port and write it into txt-File 会有帮助?