Search code examples
casynchronouswinapiipcnamed-pipes

how to send data at any moment ( simultaneous ) in windows?


I want write a namedpipe client in windows OS, which can send data at any time even the client is receiving data.Example of MSDN only shows that sending data after receive something.And the serial operation is not what I want. Because the data I transfer between client and server is not so big,that is to say, IO operation should not be a time-consuming process, I didn't use OVERLAP in client.

The code that I modify in MSDN example of client is as below: the main thread keep reading data, and the child-thread keep sending data to server. However, the server blocked when reading data when debugging.

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();

I expect someone can correct that code to get it work, or can you tell the standard practice or suggestions? Thanks so much!


Solution

  • from CreateFile documentation about FILE_FLAG_OVERLAPPED

    If this flag is specified, the file can be used for simultaneous read and write operations.

    If this flag is not specified, then I/O operations are serialized

    I/O operations are serialized mean that the new I/O request will be wait until previous not complete. so even use multiple threads here not help, if you not use FILE_FLAG_OVERLAPPED. for example you can from one thread begin read operation and wait until data not exist. if you call write on this file from another thread - write will be wait in I/O subsystem code, until your read not complete. even if you say query file name (via GetFileInformationByHandleEx with FileNameInfo) this request will be serialized and wait until your read not completed.

    so only option for simultaneous I/O operations (not only read write but all) use FILE_FLAG_OVERLAPPED when you create file.