Win32API 名前付きパイプによるプロセス間通信 CreateNamedPipe

Win32APIで名前付きパイプを用いてプロセス間通信を行う


使用するAPI

  • CreateNamedPipe

  • ConnectNamedPipe

  • DisconnectNamedPipe



  • CreateNamedPipeについて

    HANDLE CreateNamedPipe(
      LPCTSTR lpName,                             // パイプ名
      DWORD dwOpenMode,                           // パイプを開くモード
      DWORD dwPipeMode,                           // パイプ固有のモード
      DWORD nMaxInstances,                        // インスタンスの最大数
      DWORD nOutBufferSize,                       // 出力バッファのサイズ
      DWORD nInBufferSize,                        // 入力バッファのサイズ
      DWORD nDefaultTimeOut,                      // タイムアウトの間隔
      LPSECURITY_ATTRIBUTES lpSecurityAttributes  // セキュリティ記述子
    );




    dwOpenMode

    PIPE_ACCESS_DUPLEX双方向のパイプ
    PIPE_ACCESS_INBOUNDデータの流れは、クライアントからサーバーへの方向に限定される
    PIPE_ACCESS_OUTBOUNDデータの流れは、サーバーからクライアントへの方向に限定される



    サーバー側

    #include <string.h>
    #include <stdio.h>
    #include <windows.h>
    
    int main()
    {
    	HANDLE hPipe;
    	char szBuff[256];
    	DWORD dwNumberOfBytesRead;
    
    	hPipe = CreateNamedPipe("\\\\.\\pipe\\mypipe", //lpName
    		PIPE_ACCESS_DUPLEX,		       //dwOpenMode
    		PIPE_TYPE_BYTE | PIPE_WAIT,	       //dwPipeMode
    		3,				       //nMaxInstances
    		0,				       //nOutBufferSize
    		0,				       //nInBufferSize
    		100,				       //nDefaultTimeOut
    		NULL);				       //lpSecurityAttributes
    
    	if (hPipe == INVALID_HANDLE_VALUE) {
    		return 1;
    	}
    
    	if (!ConnectNamedPipe(hPipe, NULL)) {
    		CloseHandle(hPipe);
    		return 1;
    	}
    
    	while (1) {
    		if (!ReadFile(hPipe, 
    			szBuff, 
    			sizeof(szBuff),
    			&dwNumberOfBytesRead, NULL)) {
    			break;
    		}
    		szBuff[dwNumberOfBytesRead] = '\0';
    		printf("PipeServer: %s", szBuff);
    	}
    
    	FlushFileBuffers(hPipe);
    
    	DisconnectNamedPipe(hPipe);
    
    	CloseHandle(hPipe);
    
    	return 0;
    }


    クライアント側

    #include <string.h>
    #include <stdio.h>
    #include <windows.h>
    
    int main()
    {
    	HANDLE hPipe;
    	char szBuff[32];
    	DWORD dwNumberOfBytesRead;
    	DWORD dwNumberofBytesWritten;
    
    	hPipe = CreateFile("\\\\.\\pipe\\mypipe",
    		GENERIC_READ | GENERIC_WRITE,
    		0,
    		NULL,
    		OPEN_EXISTING,
    		FILE_ATTRIBUTE_NORMAL,
    		NULL);
    
    	if (hPipe == INVALID_HANDLE_VALUE) {
    		return 1;
    	}
    
    	while (1) {
    		fgets(szBuff, sizeof(szBuff)/sizeof(szBuff[0]), stdin);
    		if (!WriteFile(hPipe, szBuff, strlen(szBuff), &dwNumberofBytesWritten, NULL)) {
    			break;
    		}
    	}
    
    	CloseHandle(hPipe);
    
    	return 0;
    }



  • 使い方

  • 1.まず、サーバー側を起動してパイプを作成する

    2.クライアントを実行する。

    3.クライアントのコンソールから文字列を入力して、文字列がサーバー側のコンソールに表示されればパイプでのデータ通信が成功している。