【问题标题】:Why is my serial read on Windows COM port limited to 8192 bytes?为什么我在 Windows COM 端口上的串行读取限制为 8192 字节?
【发布时间】:2019-01-22 17:09:47
【问题描述】:

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

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

And(非重叠只读代码 sn-p)

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 个字节。

【问题讨论】:

  • 数组的定义是什么:line_buf[]
  • 代码是否试图读取刚刚写入 COM 端口的数组?有什么硬件可以实际回显数据?您的代码是否检查写入操作的结果以确保所有数据都已写入?丢失的数据是从写入数据的开头还是结尾?
  • 为什么要投到(void *) fd,这让我觉得代码正在做一些尚未发布但不应该发布的事情。推荐minimal reproducible example
  • 简单,我使用 fd 作为套接字或指针,它是一个需要强制转换的长整数(实际上只是没有警告)。那个,我没有问题。至于数据和数组的性质,我给出命令“FORM4; OUTPDATA?;”到 USB 到 GPIB 适配器,适配器响应 20100 个格式化 S 参数数据的 ASCII 字符,实数/虚数对以逗号和 CR 分隔。仅呈现前 8192 个字节。

标签: c windows serial-port usb


【解决方案1】:

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

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

SetupComm function

初始化指定通信设备的通信参数。
语法 C++

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

参数
hFile
通信设备的句柄。 CreateFile 函数返回此句柄。

dwInQueue
设备内部输入缓冲区的推荐大小,以字节为单位。

dwOutQueue
设备内部输出缓冲区的推荐大小,以字节为单位。

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

获取或设置 SerialPort 输入缓冲区的大小。
C#

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

物业价值
Int32
缓冲区大小,以字节为单位。默认值为 4096;最大值是正整数,即 2147483647。

【讨论】:

    【解决方案2】:

    这更像是一个评论而不是一个答案。根据接受的答案,增加缓冲区大小将在 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 会有所帮助?

    【讨论】:

    • 没错,我对 Select() 了如指掌,并且经常使用它。我将它用于 Windows/Linux TCP 套接字和 Linux 串行通信。在 Windows 串行通信中没有它是我必须首先重写代码的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    相关资源
    最近更新 更多