ReadFile + Eof Char

时间:2014-04-15 11:36:21

标签: c++ winapi serial-port

我使用串行通讯端口同步与WinApi进行通信。我想用 13 (CR)拆分消息。如何使用ReadFile function使其在读取13时返回?

<小时/> DCB结构有一个名为EofChar的字段,但该函数继续读取,直到它填满缓冲区。如果我只用13发送3个字节,它继续等待另外2个字节。实际上是否可以使ReadFile读取的字节数少于缓冲区提供的nNumberOfBytesToRead所指定的字节数?

  • 传入的十进制字节:12 12 13 15 18 19 ...
  • 通缉十进制字节:12 12 13(但未知长度)

<小时/> 的代码:

// 2. reading:
DWORD bytesRead;
char* buffer = new char[5];
ReadFile(handle, buffer, 5, &bytesRead, NULL);
// bytesRead should be 3 in the example above

// 1. connecting:
HANDLE handle = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
DCB dcb;
COMSTAT stat;
if (GetCommState(handle, &dcb))
{
    dcb.BaudRate          = 57600;      // baud rate
    dcb.ByteSize          = 7;          // number of bits/byte, 4-8 
    dcb.Parity            = EVENPARITY; // 0-4=no,odd,even,mark,space 
    dcb.StopBits          = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2  V2.12 0 -> ONESTOPBIT
    dcb.fBinary           = TRUE;       // binary mode, no EOF check 
    dcb.fParity           = TRUE;       // enable parity checking 
    dcb.fOutxCtsFlow      = FALSE;      // CTS output flow control 
    dcb.fOutxDsrFlow      = FALSE;      // DSR output flow control 
    dcb.fDtrControl       = 0;          //DTR_CONTROL_DISABLE; // DTR flow control type
    dcb.fRtsControl       = 0;          //RTS_CONTROL_DISABLE; // RTS flow control 
    dcb.fDsrSensitivity   = FALSE;      // DSR sensitivity 
    dcb.fTXContinueOnXoff = FALSE;      // XOFF continues Tx 
    dcb.fOutX             = FALSE;      // XON/XOFF out flow control 
    dcb.fInX              = FALSE;      // XON/XOFF in flow control 
    dcb.fErrorChar        = FALSE;      // enable error replacement V2.12 TRUE -> FALSE
    dcb.fAbortOnError     = TRUE;       // abort reads/writes on error 
    dcb.XonChar           = 0x00;       // Tx and Rx XON character 0x01
    dcb.XoffChar          = 0x00;       // Tx and Rx XOFF character 0x02
    dcb.ErrorChar         = 0x1f;       // error replacement character  
    dcb.EofChar           = 0x0d;       // end of input character 0x00
    dcb.EvtChar           = 0x00;       // received event character 0x0d

    if (SetCommState(handle, &dcb))
    {
        EscapeCommFunction(handle, SETRTS);
        EscapeCommFunction(handle, SETDTR);
        EscapeCommFunction(handle, CLRRTS);
        EscapeCommFunction(handle, CLRDTR);
        PurgeComm(handle, PURGE_TXCLEAR | PURGE_RXCLEAR);
        return true;
    }
}

1 个答案:

答案 0 :(得分:0)

不,这不太可能奏效。 Windows本身不会对您指定的DCB.EofChar执行任何操作。或者就此而言,DCB中的任何其他特殊字符。它直接将其传递给设备驱动程序,底层ioctl为IOCTL_SERIAL_SET_CHARS。完全由驱动程序来实现它们。

大多数硬件供应商编写串行端口驱动程序(目前大多数情况下都是USB模拟器),使用WDK中包含的示例驱动程序代码。哪个没有与SERIAL_CHARS.EofChar。所以不可避免的结果是没有人实现它。无论如何,我个人从来没有遇到过。

所以预计不会产生任何影响。

您通常可以期望DCB.EvtChar工作,它为WaitCommEvent()的EV_RXFLAG选项提供支持。换句话说,如果你将它设置为行终止符,那么它可以给你一个信号,说明ReadFile()将返回至少一个完整的行。

但你明确表示你不想这样做。每个人都通过简单地缓冲ReadFile()返回的额外数据来解决这个问题。或者通过一次读取一个字节,这是可以的,因为无论如何串口都很慢。