[an error occurred while processing this directive]
[an error occurred while processing this directive]c:\> pipe_server.exe hogeみたいに引数をなんかつけて実行すると、サーバーモードで、新しく名前付きpipeを作ります。
c:\> pipe_server.exeみたいに引数をつけないと、クライアントモードで、既存の名前付きpipeに接続します。
// pipe_server.cpp : パイプのサンプル // // includeするもの: // #include <windows.h> // #include <conio.h> // #include <process.h> // #include <iostream> #include "stdafx.h" #define PIPE_NAME "\\\\.\\pipe\\hello_pipe3" #define TIME_OUT 120 * 1000 bool debug = false; /** エラーを表示して終了する */ void err_exit(char *cp){ DWORD eno = GetLastError(); std::cerr << "Error: " << cp << " errcode=" << eno << std::endl; ExitProcess(eno); } /** エラーを表示して、パイプを閉じて終了する */ void err_close_exit(char *cp, HANDLE h){ int eno = GetLastError(); std::cerr << "Error: " << cp << " errcode=" << eno << std::endl; CloseHandle(h); ExitProcess(eno); } class PipeBase { /** * パイプのベースクラス (read/writeを備える) */ protected: HANDLE hPipe; public: void read(char *buf, int buflen, int read_len){ /** バッファbuf(長さbuflen)に、read_lenで指定されたバイト数読み込む。*/ int already_read = 0; if(read_len >= buflen) err_close_exit("Too small buffer", hPipe); while(already_read < read_len){ DWORD actual_len; int ret = ReadFile(hPipe, buf + already_read, read_len - already_read, &actual_len, NULL); if(debug) std::cout << "Read "<< actual_len << " bytes" << std::endl; already_read += actual_len; if(!ret) err_close_exit("ReadFile", hPipe); } // おせっかいかもしれないけど、coutとかでうまく表示できるように最後を\0でつぶしておく。 buf[read_len] = '\0'; if(debug) std::cout << "Server read: " << buf << std::endl; } void write(char *buf, int write_len){ if(debug) std::cerr << "% Writing to HANDLE " << hPipe << std::endl; /** バッファbufから、write_lenで指定されたバイト数書き込む。*/ int already_written = 0; while(already_written < write_len){ DWORD actual_len; int ret = WriteFile(hPipe, buf + already_written, write_len - already_written, &actual_len, NULL); if(debug) std::cout << "% Wrote "<< actual_len << " bytes" << " (tried to write " << write_len << ")" << std::endl; already_written += actual_len; if(!ret) err_close_exit("WriteFile", hPipe); } } }; class PipeServer : public PipeBase { /** パイプのサーバ (名前付きパイプを作り、clientからの入力を待つ) */ public: PipeServer(char *pipe_name, int dwBufferSize = 1024){ /** * コンストラクタ。 * パイプを作り、クライアントの接続を待つ。 */ hPipe = CreateNamedPipe( pipe_name, /* パイプ名 */ PIPE_ACCESS_DUPLEX, /* 双方向 */ PIPE_WAIT /* ブロッキング・モード */ | PIPE_READMODE_BYTE /* バイト・モード */ | PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, /* インスタンス数の制限なし */ dwBufferSize, /* 出力バッファ・サイズ */ dwBufferSize, /* 入力バッファ・サイズ */ TIME_OUT, /* タイムアウト */ NULL); /* セキュリティ属性なし */ if(hPipe == INVALID_HANDLE_VALUE){ int eno = GetLastError(); if(eno == 123){ std::cerr << "Pipename format is wrong" << std::endl; ExitProcess(eno); } else { err_exit("CreateNamedPipe"); } } if(debug) std::cerr << "% Pipe has successfully created" << std::endl; // クライアントの接続待ち int ret = ConnectNamedPipe(hPipe, NULL); if(!ret) err_close_exit("ConnectNamedPipe", hPipe); if(debug) std::cerr << "% Client has connected" << std::endl; } ~PipeServer(){ CloseHandle(hPipe);} }; class PipeClient : public PipeBase { /** パイプのクライアント (名前付きパイプを作り、サーバに接続する) */ public: PipeClient(char *pipe_name, int dwBufferSize = 1024){ /** * コンストラクタ。 * 名前を指定して、パイプに接続する。 */ hPipe = CreateFile(pipe_name, /* パイプ名 */ GENERIC_WRITE | GENERIC_READ, /* 読み書きアクセス */ FILE_SHARE_READ | FILE_SHARE_WRITE, /* 読み書きアクセス共有 */ NULL, /* セキュリティ属性なし */ OPEN_EXISTING, /* 既存の名前付きパイプに接続 */ FILE_ATTRIBUTE_NORMAL, /* ファイル属性なし */ NULL); /* テンプレート・ファイルなし */ std::cerr << "HANDLE " << hPipe << std::endl; if (hPipe == INVALID_HANDLE_VALUE) { int eno = GetLastError(); if(eno == ERROR_FILE_NOT_FOUND){ std::cerr << "Specified Pipe Not Found" << std::endl; ExitProcess(eno); } else { err_exit("CreateFile"); } } if(debug) std::cerr << "Successfully connected to the named-pipe" << std::endl; } ~PipeClient(){ CloseHandle(hPipe);} }; int main(int argc, char* argv[]) { if(argc == 2){ PipeServer ps(PIPE_NAME); const int LEN = 1024; char buf[LEN]; ps.read(buf, LEN, 5); std::cerr << "Received " << buf << std::endl; } else { char *cp = "hello"; PipeClient pc(PIPE_NAME); pc.write(cp, 5); Sleep(100); std::cerr << "Sent " << cp << std::endl; } return 0; }