Member 12330615 Ответов: 2

Как установить параметр overlapped в файле readfile?


Привет
Я хотел бы получать данные через асинхронный последовательный порт с другого сервера, кодируя VC++.

Я использую функцию ReadFile() примерно так:

char buf[1024];
размер = 1;

ReadFile (hComm, buf, size, dwRead, 0);

Это может принимать данные один байт и один байт последовательно.

Но любое действие во время приема может привести к потере данных с вышеприведенного порта в случае смены потока или более быстрой скорости передачи данных.

Поэтому я бы изменил состояние С сигнального состояния на управляемое событиями, используя перекрывающуюся структурную переменную.

Как новичку, мне очень трудно найти образец ReadFile (), используя последний параметр overlapped.

Чтобы получить безопасно, мне было рекомендовано, чтобы "использование перекрывающейся переменной" в ReadFile() не теряло ни одного символа в последовательной связи - это правильно?

Поэтому, пожалуйста, дайте мне знать метод с правильным образцом его.

Спасибо.

Что я уже пробовал:

Еще 1 неделя потрачена впустую на эту проблему.

2 Ответов

Рейтинг:
5

Jochen Arndt

Упрощенный пример и описания можно найти по адресу последовательная связь[^].

При использовании перекрывающегося ввода-вывода вы должны передать перекрывающуюся структуру всем ReadFile() и WriteFile() звонки. Для каждой операции, которая может находиться в состоянии ожидания, необходимо создать событие, поместить дескриптор события в соответствующую перекрывающуюся структуру и вызвать WaitForSingleObject() / WaitForMultipleObjects() и GetOverlappedResult() когда произошло это событие.

Но при последовательном приеме часто не предсказуемо, сколько байтов может быть получено. Затем вы также можете использовать последовательные события для уведомления о поступлении данных. Чтобы сделать этот вызов SetCommMask() с EV_RXCHAR и необязательно EV_ERR, и в цикле приема WaitCommEvent() проходим мимо еще одной перекрывающейся конструкции. Я предоставил пример кода один раз в этом решении CP: Проблема последовательной связи[^]

На самом деле EV_RXCHAR и EV_ERR тогда звонят события ClearCommError() чтобы проверить наличие ошибок и получить количество доступных байтов. При передаче количества доступных байтов из вышеперечисленного в ReadFile(), вы можете просто использовать пустую перекрывающуюся структуру там, потому что вызов вернется немедленно (без ожидания). При использовании кода из моего вышеприведенного решения он должен выглядеть следующим образом:

// At begin of receive thread function
OVERLAPPED ovRead = {0};

// Inside loop after waiting
if (nEvent & (EV_RXCHAR | EV_ERR))
{
    DWORD dwComErrors = 0;
    COMSTAT tComStat;
    ::ClearCommError(m_hCom, &dwComErrors, &tComStat);
    if (dwComErrors)
    {
        // handle error here
    }
    if (tComStat.cbInQue)
    {
        DWORD dwRead;
        // Ensure that pBuf is large enough.
        // If not, read and process data in chunks.
        // This call will succeed (no pending) because we know how many data
        //  are available.
        // So we can pass an empty overlapped structure here.
        ::ReadFile(m_hCom, pBuf, tComStat.cbInQue, &dwRead, &ovRead);
    }
}

Цитата:
Чтобы получить безопасно, мне было рекомендовано, чтобы "использование перекрывающейся переменной" в ReadFile() не теряло ни одного символа в последовательной связи - это правильно?
Это неправильно, потому что внутренний буфер приема все еще может переполняться, когда события приема не обрабатываются вовремя.


Рейтинг:
1

Richard MacCutchan

Я не знаю, почему вы потратили впустую неделю, но Google потребовалась 1 секунда, чтобы найти Синхронизация и перекрытие ввода и вывода (Windows)[^].