Skip to content

Instantly share code, notes, and snippets.

@mmozeiko
Last active March 15, 2024 13:06
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mmozeiko/8024e4bc5aeef45da7dd92229f7049af to your computer and use it in GitHub Desktop.
Save mmozeiko/8024e4bc5aeef45da7dd92229f7049af to your computer and use it in GitHub Desktop.
Example how to use read-only named pipes with single client in non-blocking way on single thread
#include <windows.h>
#include <stdio.h>
#include <assert.h> // for potential error handling, change to real errors in your code
int main()
{
HANDLE pipe = CreateNamedPipeW(
L"\\\\.\\pipe\\lolcat",
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
1, 4096, 4096, 0, NULL);
assert(pipe != INVALID_HANDLE_VALUE);
OVERLAPPED ov = {};
ov.hEvent = CreateEventW(NULL, FALSE, TRUE, NULL);
assert(ov.hEvent);
enum { StateStartConnect, StateConnecting, StateConnected, StateReading, StateReadFinished, StateDisconnected };
int state = StateStartConnect;
DWORD size;
char buffer[4096];
for (;;)
{
int wait = WaitForSingleObject(ov.hEvent, 0);
if (wait == WAIT_OBJECT_0)
{
bool blocking = false;
while (!blocking)
{
switch (state)
{
case StateStartConnect:
{
if (ConnectNamedPipe(pipe, &ov))
{
state = StateConnected;
}
else
{
assert(GetLastError() == ERROR_IO_PENDING);
state = StateConnecting;
blocking = true;
}
break;
}
case StateConnecting:
{
printf("Client connected\n");
state = StateConnected;
break;
}
case StateConnected:
{
if (ReadFile(pipe, buffer, sizeof(buffer), &size, &ov))
{
state = StateReadFinished;
}
else
{
int err = GetLastError();
if (err == ERROR_BROKEN_PIPE)
{
state = StateDisconnected;
}
else
{
assert(err == ERROR_IO_PENDING);
state = StateReading;
blocking = true;
}
}
break;
}
case StateReading:
{
if (GetOverlappedResult(pipe, &ov, &size, TRUE))
{
state = StateReadFinished;
}
else
{
assert(GetLastError() == ERROR_BROKEN_PIPE);
state = StateDisconnected;
}
break;
}
case StateReadFinished:
{
printf("%u bytes was read from pipe\n", size);
// here you can process size bytes from buffer
// ...
state = StateConnected;
break;
}
case StateDisconnected:
{
printf("Client disconnected\n");
DisconnectNamedPipe(pipe);
state = StateStartConnect;
break;
}
}
}
}
else
{
assert(wait == WAIT_TIMEOUT);
}
// some stuff happens here
// ...
printf(".");
Sleep(100);
}
// cleanup
// CloseHandle(ov.hEvent);
// CloseHandle(pipe);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment