プログラミングメモ →目次

名前付きパイプ(簡易版)(VC++)

Named Pipe

名前付きパイプで、プロセス間の通信についてのメモです。流れとしては、
(1)サーバープロセスがCreateNamedPipe()関数でパイプのインスタンスを作成します。
(2)サーバープロセスがConnectNamedPipe()関数を呼び出して、(3)のクライアントからの接続を待ちます。
(3)クライアントプロセスがCreateFile()関数でパイプのインスタンスに接続します。

例:インスタンスの数が1である場合の処理。

サーバー側の処理
1.名前付きパイプを作って、クライアント側の接続を待ちます。

HANDLE hPipeServer = INVALID_HANDLE_VALUE;
void CreatePipeServerSide()
{
    hPipeServer = CreateNamedPipe("\\\\.\\pipe\\test", PIPE_ACCESS_DUPLEX, 
                                  PIPE_TYPE_BYTE | PIPE_WAIT, 1, 0, 0, 1000, 0);
    if(hPipeServer == INVALID_HANDLE_VALUE)
        return;

    if (!ConnectNamedPipe(hPipeServer, NULL))
    {
        CloseHandle(hPipeServer);
        hPipeServer = INVALID_HANDLE_VALUE;
    }
}
2.パイプにデータをライトします。
void WritePipeServerSide()
{
    if (hPipeServer != INVALID_HANDLE_VALUE)
    {
        char* buff = "Hi, I an the pipe server.";
        DWORD    nBytes;
        WriteFile(hPipeServer, buff, strlen(buff), &nBytes, NULL);
    }
}
3.パイプからデータをリードします。
void ReadPipeServerSide()
{
    if (hPipeServer != INVALID_HANDLE_VALUE)
    {
        DWORD    nBytes;
        char    buff[1024];
        memset(buff, NULL, sizeof(buff));
        if (ReadFile(hPipeServer, buff, 10, &nBytes, NULL))
            AfxMessageBox(buff);
    }
}
4.パイプをクローズします。
void ClosePipeServerSide()
{
    if (hPipeServer != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hPipeServer);
        hPipeServer = INVALID_HANDLE_VALUE;
    }
}
クライアント側の処理
1.CreateFile()関数でパイプのインスタンスに接続します。
HANDLE hPipeClient = INVALID_HANDLE_VALUE;
void ConnectTestPipe()
{
    hPipeClient = CreateFile("\\\\.\\pipe\\test", 
                  GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
}
2.パイプにデータをライトします。
void WriteClientSide()
{
    if (hPipeClient != INVALID_HANDLE_VALUE)
    {
        DWORD nBytes;
        char* buff = "Hello, I am Client side of the Pipe.";
        WriteFile(hPipeClient, buff, strlen(buff), &nBytes, NULL);
    }
}
3.パイプからデータをリードします。
void ReadClientSide()
{
    if (hPipeClient != INVALID_HANDLE_VALUE)
    {
        DWORD    nBytes;
        char    buff[1024];
        memset(buff, NULL, sizeof(buff));
        if(ReadFile(hPipeClient, buff, 10, &nBytes, NULL))
            AfxMessageBox(buff);
    }
}
4.パイプをクローズします。
void ClosePipeClientSide()
{
    if (hPipeClient != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hPipeClient);
        hPipeClient = INVALID_HANDLE_VALUE;
    }
}
注意:テストする時に、サーバー側とクライアント側を別々の実行ファイルします。スレッドを使わなくても、テストに問題ないですが、実際のアプリを作る場合は、スレッドを使います。