名前付きパイプ(複数インスタンス)(VC++) Named Pipe #define NMAXINSTANCES 3 HANDLE g_hPipeListen[NMAXINSTANCES] = {INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; HANDLE hThreadListen[NMAXINSTANCES] = {NULL,NULL,NULL}; void CreateListenPipeThread() { bEndProc = FALSE; for (int i = 0; i < NMAXINSTANCES; i ++) { g_hPipeListen[i] = CreateNamedPipe("\\\\.\\pipe\\test", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT, NMAXINSTANCES, 0, 0, NMPWAIT_WAIT_FOREVER, 0); hThreadListen[i] = CreateThread(NULL, 0, ListenPipeThread, (LPVOID)i, 0, NULL); hThreadWrite[i] = CreateThread(NULL, 0, WritePipeThread, (LPVOID)i, 0, NULL); hEventWrite[i] = CreateEvent(NULL, TRUE, FALSE, NULL); } }パイプのインスタンスを作りながら、インスタンス毎に、リスニング(=パイプ接続待ち)のスレッドとライトのスレッドを作ります。メルチスレッド無しで、パイプを 利用できないですね。 DWORD WINAPI ListenPipeThread(LPVOID lpParam) { int iNo = (int)lpParam; while (!bEndProc) { OVERLAPPED ovlp; HANDLE hEvent; memset(&ovlp, 0, sizeof(OVERLAPPED)); hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ovlp.hEvent = hEvent; if (!ConnectNamedPipe(g_hPipeListen[iNo], &ovlp)) { if (GetLastError() == ERROR_IO_PENDING) { WaitForSingleObject(hEvent, INFINITE); } else if (GetLastError() == ERROR_PIPE_CONNECTED) { CloseHandle(hEvent); continue; } bListening[iNo] = TRUE; ReadPipe(iNo); } DisconnectNamedPipe(g_hPipeListen[iNo]); bListening[iNo] = FALSE; } return 0; }リスニングのスレッドの中で、まずクライアントプロセスがパイプのインスタンスに接続してくるのを待機します。接続されたら、繰り返してパイプをリ ードをして見ます。この間、クライアント側などの原因でリードが不可能になれば、今現在の接続を自ら切断して、またパイプのインスタンスに接続してくるのを待機すること路から繰り返します。パイプのリードは下記のようです。 void ReadPipe(int iNo) { while (!bEndProc && bListening[iNo]) { OVERLAPPED ovlp; HANDLE hEvent; memset(&ovlp, 0, sizeof(OVERLAPPED)); hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ovlp.hEvent = hEvent; DWORD nBytes = 0; char buff[1024]; memset(buff, NULL, sizeof(buff)); BOOL bRet = ReadFile(g_hPipeListen[iNo], buff, 10, &nBytes, &ovlp); if (!bRet) { if (GetLastError() == ERROR_IO_PENDING) { WaitForSingleObject(hEvent, INFINITE); bRet = GetOverlappedResult(g_hPipeListen[iNo], &ovlp, &nBytes, TRUE); } } CloseHandle(hEvent); if (bRet) { if (nBytes) { TRACE("受信%d: %s\r\n", iNo, buff); for (int i = 0; i < NMAXINSTANCES; i ++) { if (i != iNo && g_hPipeListen[i] != INVALID_HANDLE_VALUE) { strcpy(send_buff[i], buff); SetEvent(hEventWrite[i]); Sleep(10); } } } } else { break; } } }OVERLAPPEDで受信をします。一つのクライアントから受信したら、他のクライアントへ転送します。受信エラーが発生するまで繰り返します。 テスト用のソース(pipetest.cpp) |