.NET CORE Serial Class 在使用 tty 端口发布到 Linux 机器时未读取 BaseStream 或 ReadBuffer 中超过 4KBytes 的数据

.NET CORE Serial Class not reading data past 4KBytes in BaseStream or ReadBuffer when published to Linux machine using tty ports

我构建了一个串行端口文件传输 .NET CORE 3.0 应用程序,它在 windows 上运行良好,但在 linux 上只能读取少量数据。基本上我从一台机器传输数据,接收机器读取数据是这样的:

        _serialPort.ReadBufferSize = 7000000;
...more setup code 

        Console.WriteLine("Serial receiver started at " + DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture) + " Collecting and decoding file data for 4 minute intervals. Please wait...");
        Console.WriteLine("Header search pattern: " + BitConverter.ToString(BitConverter.GetBytes(header)));
        int sleepTimeMiliseconds = (240000 - (int)stopwatch.Elapsed.TotalMilliseconds < 1) ? 0 : 240000 - (int)stopwatch.Elapsed.TotalMilliseconds;
        Thread.Sleep(sleepTimeMiliseconds); // wait for about 4 minutes for the data to come in.
        byte[] dataBuffer = new byte[_serialPort.ReadBufferSize];

        //read data then discard buffer to get new data from the transmitting machine
        if (!_serialPort.IsOpen) // serial port could close when operating system sleeps
            _serialPort.Open();
        _serialPort.Read(dataBuffer, 0, dataBuffer.Length);
        //HundredKBBuffer = Convert.FromBase64String(_serialPort.ReadExisting());
        _serialPort.DiscardInBuffer();
        stopwatch.Restart();
        Console.WriteLine("Data buffer size in bytes: " + dataBuffer.Length);
        DecodeFileData(dataBuffer, header, trailer);

我也尝试过使用 _serialPort.BaseStream.Read(dataBuffer, 0, dataBuffer.Length); 而不是 _serialPort.Read(dataBuffer, 0, dataBuffer.Length);,但同样的问题发生了。我从未在缓冲区中看到任何超过 4096 的字节,所以我不确定如何在 linux 环境中实现这一点。缓冲区大小是否更小且不可更改?我已经使用了 _serialPort.ReadBufferSize = 7000000; 但它似乎并没有帮助解决这个问题。 linux 机器是 CentOS 或 Redhat

4KBytes 是 tty 缓冲区的限制。内核有一个 4096 字节的内部缓冲区。如果此缓冲区已满并且新字节到达串行端口,则缓冲区中最旧的字节将被覆盖并因此丢失。

我解决了 .NET CORE 3.0 不允许我设置 _serialPort.ReadBufferSize 的问题,方法是基本上使用 "stream byte reader" 方法并沿我的自定义字节 [] 缓冲区递增我的当前索引在我之前的读取操作中读取了很多字节(轮询以填充我的自定义缓冲区)。

                    byte[] dataBuffer = new byte[3000000]; // big enough buffer
                    bool singleReadIterationFinished = false;
                    while (!singleReadIterationFinished)
                    {
                        Task<int> bytesReadFromPort = _serialPort.BaseStream.ReadAsync(dataBuffer, bufferOffset, dataBuffer.Length - bufferOffset); // read as many bytes as available at a time

                        //other code can go here since the thread isn't blocked 

                        bufferOffset += bytesReadFromPort.Result; // From docs.Microsoft: Calling the result properties get accessor will block the calling thread until the asyncrhonous operation is complete; this is equivalent to calling 'Wait' method.
                        if (bufferOffset > 2000000) // wait for 2megabytes of data. change this to megabytes. 
                        {
                            Console.WriteLine("Read a total of : " + bufferOffset + " Bytes");
                            byte[] copyBuffer = new byte[dataBuffer.Length];
                            Array.Copy(dataBuffer, 0, copyBuffer, 0, dataBuffer.Length);
                            DecodeFileData(copyBuffer, header, trailer); // need to call this asyncronously
                            singleReadIterationFinished = true;
                        }
                    }