A Named Pipe is a mechanism for communication between processes. One process has to create the Named Pipe (termed as pipe server) and one or more processes can connect to this Named Pipe (pipe clients) using the unique name given to it, when it was created.
A Named Pipe can be used for both unidirectional as well as bidirectional data transfer between the server and client, once a connection is established. This simple example demonstrates the basics of creating and managing a Named Pipe using WIN32 APIs, connecting to it through a client program (Java application) and performing bidirectional data communication.
WIN32 Application (Pipe Server)
#include "stdafx.h"
#include "windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
do
{
DWORD error = 0; DWORD bytesRead = 0; DWORD bytesWritten = 0; BYTE pipeData = 0x00; BOOL result = FALSE; const TCHAR * pipeName = _T("\\\\.\\pipe\\MyWindowsNamedPipe");
HANDLE hPipe = CreateNamedPipe(pipeName,
PIPE_ACCESS_DUPLEX,
0,
(PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT),
PIPE_UNLIMITED_INSTANCES,
512,
0,
NULL);
if (hPipe == INVALID_HANDLE_VALUE)
{
_tprintf(_T("Create named pipe with name %s failed.
Error Code %08X.\n"), pipeName, GetLastError());
break;
}
_tprintf(_T("Waiting for client connection...\n"), GetLastError());
result = ConnectNamedPipe(hPipe, NULL);
if (result == FALSE)
{
_tprintf(_T("Wait for client connection failed.
Error Code %08X.\n"), GetLastError());
break;
}
else
{
_tprintf(_T("Client connected.\n"), GetLastError());
}
while (true)
{
bytesRead = 0;
result = ReadFile(hPipe, &pipeData, 1, &bytesRead, NULL);
if (bytesRead == 1)
{
if (pipeData == 0xFF)
{
_tprintf(_T("Exit command received.\n"));
break;
}
else
{
WriteFile(hPipe, &pipeData, 1, &bytesWritten, NULL);
if (bytesWritten == 0)
{
_tprintf(_T("Write to pipe failed.
Error Code %08X.\n"), GetLastError());
break;
}
}
}
else
{
_tprintf(_T("Read from pipe failed.
Error Code %08X.\n"), GetLastError());
break;
}
}
CloseHandle(hPipe);
} while (false);
system("PAUSE");
return 0;
}
Java Application (Pipe Client)
package com.test.NamedPipe;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class NamedPipeClient {
public static void main(String[] args) {
try {
final String pipeName = "\\\\.\\pipe\\MyWindowsNamedPipe";
final String pipeData = "Hello Pipe";
final byte[] pipeDataBytes = pipeData.getBytes();
RandomAccessFile pipe = new RandomAccessFile(pipeName, "rw");
try {
for (int i = 0; i < pipeData.length(); i++) {
System.out.println("Writing data byte 0x" +
Integer.toHexString(pipeDataBytes[i]) +
" (" + ((char)pipeDataBytes[i]) + ") " +
"to pipe...");
pipe.write(pipeDataBytes[i]);
do {
int rxData = pipe.read();
System.out.println("Byte read from pipe: 0x" +
Integer.toHexString(rxData) +
" (" + ((char)rxData) + ")");
} while (pipe.length() > 0);
System.out.println();
}
pipe.write(0xFF);
} catch (IOException e) {
e.printStackTrace();
}
pipe.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}