Как отправить данные в любой момент (одновременно) в Windows? - PullRequest
0 голосов
/ 13 января 2019

Я хочу написать клиент namedpipe в ОС Windows, который может отправлять данные в любое время, даже если клиент получает данные. Пример MSDN показывает только то, что отправка данных происходит после получения чего-либо. не то, что я хочу. Поскольку данные, которые я передаю между клиентом и сервером, не так велики, то есть операция ввода-вывода не должна занимать много времени, я не использовал OVERLAP в клиенте.

Код, который я изменяю в примере клиента MSDN, приведен ниже: основной поток продолжает читать данные, а дочерний поток продолжает отправлять данные на сервер. Однако сервер заблокирован при чтении данных при отладке.

std::thread t([&] {
    cbToWrite = (lstrlen(lpvMessage) + 1) * sizeof(TCHAR);
    _tprintf(TEXT("Sending %d byte message: \"%s\"\n"), cbToWrite, lpvMessage);


    fSuccess = WriteFile(
        hPipe,                  // pipe handle
        lpvMessage,             // message
        cbToWrite,              // message length
        &cbWritten,             // bytes written
        NULL);                  // not overlapped

    if (!fSuccess)
    {
        _tprintf(TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError());
        return -1;
    }

    printf("\nMessage sent to server, receiving reply as follows:\n");

});

while (1)   // main thread always reading
{
    do
    {
        // Read from the pipe.

        fSuccess = ReadFile(
            hPipe,    // pipe handle
            chBuf,    // buffer to receive reply
            BUFSIZE * sizeof(TCHAR),  // size of buffer
            &cbRead,  // number of bytes read
            NULL);    // not overlapped

        if (!fSuccess && GetLastError() != ERROR_MORE_DATA)
            break;

        _tprintf(TEXT("\"%s\"\n"), chBuf);
    } while (!fSuccess);  // repeat loop if ERROR_MORE_DATA

    if (!fSuccess)
    {
        _tprintf(TEXT("ReadFile from pipe failed. GLE=%d\n"), GetLastError());
        return -1;
    }
}


t.join();

Я ожидаю, что кто-то может исправить этот код, чтобы он заработал, или вы можете рассказать стандартную практику или предложения? Большое спасибо!

1 Ответ

0 голосов
/ 13 января 2019

из CreateFile документация о FILE_FLAG_OVERLAPPED

Если указан этот флаг, файл может использоваться для одновременного операции чтения и записи.

Если этот флаг не указан, то операции ввода-вывода сериализуются

Операции ввода-вывода сериализуются, что означает, что новый запрос ввода-вывода будет ожидать до тех пор, пока предыдущий не будет завершен. поэтому даже использование нескольких потоков здесь не поможет, если вы не используете FILE_FLAG_OVERLAPPED. Например, вы можете из одного потока начать операцию чтения и ждать, пока данные не будут существовать. если вы вызываете write для этого файла из другого потока - write будет ждать в коде подсистемы ввода / вывода, пока ваше чтение не будет завершено. даже если вы скажете имя файла запроса (через GetFileInformationByHandleEx с FileNameInfo), этот запрос будет сериализован и будет ждать, пока чтение не будет завершено.

, поэтому единственная опция для одновременных операций ввода-вывода (не только чтение-запись, но и все) использует FILE_FLAG_OVERLAPPED при создании файла.

...