区分设备断开连接和超时

发布于 2024-11-25 04:51:37 字数 616 浏览 3 评论 0原文

使用 ReadFile< 时/a> 在通信资源上,可以通过检查读取的字节数是否少于请求的字节数来检测读取超时。例如,当我想读取1个字节时,如果读取超时,则返回0个字节,函数成功。

但是,当我从 COM 端口断开设备(读取一些字节后)并在其旧句柄上启动读取操作时,会发生同样的事情:函数成功并表示返回 0 字节。

由于当前没有可用数据,如何区分设备断开连接和简单的读取超时?

目前,我正在检查是否返回 0 字节,如果是,我检查设备是否仍使用 WMI 连接。然而,这看起来不太干净,我希望我能在这里找到更好的解决方案。

更新

有关设备的更多信息(如评论中所述):

dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;

CTS 和 DSR 均在数据传输期间以及通过从 USB 端口拔下电缆来断开设备连接后设置。

When using ReadFile on a communications resource it is possible to detect read timeouts by checking if less bytes than the requested amount of bytes were read. For example, when I want to read 1 byte, in case of a read timeout, 0 bytes are returned and the function succeeds.

However, when I disconnect the device (after reading some bytes) from the COM-Port and start a read operation on its old handle, the same thing happens: Function succeeds and says that 0 bytes were returned.

How can I distinguish between a device disconnect and a simple read timeout since no data is currently available?

Currently, I'm checking if 0 bytes were returned, and if yes, I check if the device is still connected using WMI. However, this does not look very clean and I hope that I can find a better solution here.

Update

Some more information about the device (as asked in comments):

dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;

CTS and DSR are both set during data transfer and also after the device gets disconnected by unplugging the cable from the USB port.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟雨凡馨 2024-12-02 04:51:37

如果您使用的是 Windows,则可能需要 SetCommTimeoutsFunction。您还应该查看其他通信功能 用于处理RS232。

编辑:当我将一些代码从具有实际 RS232 的手持设备移动到具有 USB RS232 的手持设备时,我遇到了非常相似的情况。晃动 USB,端口就会在应用程序不知情的情况下“丢失”。我为解决这个问题而编写的代码如下(Win32平台)

COMMTIMEOUTS    CTO;
CTO.ReadIntervalTimeout = 500;
CTO.ReadTotalTimeoutConstant = 500;
CTO.ReadTotalTimeoutMultiplier = 0;
if (SetCommTimeouts(hPort,&CTO) == 0)
{ 
    DWORD dwError = GetLastError();
    if (dwError == 5)   
    {
        // Access denied, possibly loose USB, return error code or throw exception
        return Housten__We_have_a_problem;
    }
}

If you're using Windows, you possibly need the SetCommTimeoutsFunction. You should also check out the othe communications functions for dealing with RS232.

Edit: I had a very similar situation when moving some code from a hand-held device with an actual RS232, to one with a USB RS232. Wobble the USB, and the port would get 'lost' unbeknownst to the application. The code I wrote to get around this is as follows (Win32 platform)

COMMTIMEOUTS    CTO;
CTO.ReadIntervalTimeout = 500;
CTO.ReadTotalTimeoutConstant = 500;
CTO.ReadTotalTimeoutMultiplier = 0;
if (SetCommTimeouts(hPort,&CTO) == 0)
{ 
    DWORD dwError = GetLastError();
    if (dwError == 5)   
    {
        // Access denied, possibly loose USB, return error code or throw exception
        return Housten__We_have_a_problem;
    }
}
撕心裂肺的伤痛 2024-12-02 04:51:37

只是为了完整性:

在 Linux 上,read 和 select 也返回 0,但是 tcgetattr 将在断开连接时返回错误,在超时时返回 0,所以这是一种方法。

Just for completeness:

On Linux, read and select also return 0, but tcgetattr, will return an error on disconnect and 0 on timeout, so that's one way to do it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文