命名管道
来源:互联网 发布:java设计模式书籍 编辑:程序博客网 时间:2024/05/16 12:11
MSDN里面三种命名管道服务器
多线程命名管道服务器 Multithreaded Pipe Server#include <windows.h> #include <stdio.h> #include <tchar.h>#include <strsafe.h>#define BUFSIZE 4096 DWORD WINAPI InstanceThread(LPVOID); VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD); int _tmain(VOID) { BOOL fConnected; DWORD dwThreadId; HANDLE hPipe, hThread; LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); // The main loop creates an instance of the named pipe and // then waits for a client to connect to it. When the client // connects, a thread is created to handle communications // with that client, and the loop is repeated. for (;;) { hPipe = CreateNamedPipe( lpszPipename, // pipe name PIPE_ACCESS_DUPLEX, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances BUFSIZE, // output buffer size BUFSIZE, // input buffer size 0, // client time-out NULL); // default security attribute if (hPipe == INVALID_HANDLE_VALUE) { printf("CreatePipe failed"); return 0; } // Wait for the client to connect; if it succeeds, // the function returns a nonzero value. If the function // returns zero, GetLastError returns ERROR_PIPE_CONNECTED. fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if (fConnected) { // Create a thread for this client. hThread = CreateThread( NULL, // no security attribute 0, // default stack size InstanceThread, // thread proc (LPVOID) hPipe, // thread parameter 0, // not suspended &dwThreadId); // returns thread ID if (hThread == NULL) { printf("CreateThread failed"); return 0; } else CloseHandle(hThread); } else // The client could not connect, so close the pipe. CloseHandle(hPipe); } return 1; } DWORD WINAPI InstanceThread(LPVOID lpvParam) { TCHAR chRequest[BUFSIZE]; TCHAR chReply[BUFSIZE]; DWORD cbBytesRead, cbReplyBytes, cbWritten; BOOL fSuccess; HANDLE hPipe; // The thread's parameter is a handle to a pipe instance. hPipe = (HANDLE) lpvParam; while (1) { // Read client requests from the pipe. fSuccess = ReadFile( hPipe, // handle to pipe chRequest, // buffer to receive data BUFSIZE*sizeof(TCHAR), // size of buffer &cbBytesRead, // number of bytes read NULL); // not overlapped I/O if (! fSuccess || cbBytesRead == 0) break; GetAnswerToRequest(chRequest, chReply, &cbReplyBytes); // Write the reply to the pipe. fSuccess = WriteFile( hPipe, // handle to pipe chReply, // buffer to write from cbReplyBytes, // number of bytes to write &cbWritten, // number of bytes written NULL); // not overlapped I/O if (! fSuccess || cbReplyBytes != cbWritten) break; } // Flush the pipe to allow the client to read the pipe's contents // before disconnecting. Then disconnect the pipe, and close the // handle to this pipe instance. FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); return 1;}VOID GetAnswerToRequest(LPTSTR chRequest, LPTSTR chReply, LPDWORD pchBytes){ _tprintf( TEXT("%s\n"), chRequest ); StringCchCopy( chReply, BUFSIZE, TEXT("Default answer from server") ); *pchBytes = (lstrlen(chReply)+1)*sizeof(TCHAR);}
重叠IO命名管道服务器 Named Pipe Server Using Overlapped I/O
#include <windows.h> #include <stdio.h>#include <tchar.h>#include <strsafe.h> #define CONNECTING_STATE 0 #define READING_STATE 1 #define WRITING_STATE 2 #define INSTANCES 4 #define PIPE_TIMEOUT 5000#define BUFSIZE 4096 typedef struct { OVERLAPPED oOverlap; HANDLE hPipeInst; TCHAR chRequest[BUFSIZE]; DWORD cbRead; TCHAR chReply[BUFSIZE]; DWORD cbToWrite; DWORD dwState; BOOL fPendingIO; } PIPEINST, *LPPIPEINST; VOID DisconnectAndReconnect(DWORD); BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED); VOID GetAnswerToRequest(LPPIPEINST); PIPEINST Pipe[INSTANCES]; HANDLE hEvents[INSTANCES]; int _tmain(VOID) { DWORD i, dwWait, cbRet, dwErr; BOOL fSuccess; LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); // The initial loop creates several instances of a named pipe // along with an event object for each instance. An // overlapped ConnectNamedPipe operation is started for // each instance. for (i = 0; i < INSTANCES; i++) { // Create an event object for this instance. hEvents[i] = CreateEvent( NULL, // default security attribute TRUE, // manual-reset event TRUE, // initial state = signaled NULL); // unnamed event object if (hEvents[i] == NULL) { printf("CreateEvent failed with %d.\n", GetLastError()); return 0; } Pipe[i].oOverlap.hEvent = hEvents[i]; Pipe[i].hPipeInst = CreateNamedPipe( lpszPipename, // pipe name PIPE_ACCESS_DUPLEX | // read/write access FILE_FLAG_OVERLAPPED, // overlapped mode PIPE_TYPE_MESSAGE | // message-type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode INSTANCES, // number of instances BUFSIZE*sizeof(TCHAR), // output buffer size BUFSIZE*sizeof(TCHAR), // input buffer size PIPE_TIMEOUT, // client time-out NULL); // default security attributes if (Pipe[i].hPipeInst == INVALID_HANDLE_VALUE) { printf("CreateNamedPipe failed with %d.\n", GetLastError()); return 0; } // Call the subroutine to connect to the new client Pipe[i].fPendingIO = ConnectToNewClient( Pipe[i].hPipeInst, &Pipe[i].oOverlap); Pipe[i].dwState = Pipe[i].fPendingIO ? CONNECTING_STATE : // still connecting READING_STATE; // ready to read } while (1) { // Wait for the event object to be signaled, indicating // completion of an overlapped read, write, or // connect operation. dwWait = WaitForMultipleObjects( INSTANCES, // number of event objects hEvents, // array of event objects FALSE, // does not wait for all INFINITE); // waits indefinitely // dwWait shows which pipe completed the operation. i = dwWait - WAIT_OBJECT_0; // determines which pipe if (i < 0 || i > (INSTANCES - 1)) { printf("Index out of range.\n"); return 0; } // Get the result if the operation was pending. if (Pipe[i].fPendingIO) { fSuccess = GetOverlappedResult( Pipe[i].hPipeInst, // handle to pipe &Pipe[i].oOverlap, // OVERLAPPED structure &cbRet, // bytes transferred FALSE); // do not wait switch (Pipe[i].dwState) { // Pending connect operation case CONNECTING_STATE: if (! fSuccess) { printf("Error %d.\n", GetLastError()); return 0; } Pipe[i].dwState = READING_STATE; break; // Pending read operation case READING_STATE: if (! fSuccess || cbRet == 0) { DisconnectAndReconnect(i); continue; } Pipe[i].dwState = WRITING_STATE; break; // Pending write operation case WRITING_STATE: if (! fSuccess || cbRet != Pipe[i].cbToWrite) { DisconnectAndReconnect(i); continue; } Pipe[i].dwState = READING_STATE; break; default: { printf("Invalid pipe state.\n"); return 0; } } } // The pipe state determines which operation to do next. switch (Pipe[i].dwState) { // READING_STATE: // The pipe instance is connected to the client // and is ready to read a request from the client. case READING_STATE: fSuccess = ReadFile( Pipe[i].hPipeInst, Pipe[i].chRequest, BUFSIZE*sizeof(TCHAR), &Pipe[i].cbRead, &Pipe[i].oOverlap); // The read operation completed successfully. if (fSuccess && Pipe[i].cbRead != 0) { Pipe[i].fPendingIO = FALSE; Pipe[i].dwState = WRITING_STATE; continue; } // The read operation is still pending. dwErr = GetLastError(); if (! fSuccess && (dwErr == ERROR_IO_PENDING)) { Pipe[i].fPendingIO = TRUE; continue; } // An error occurred; disconnect from the client. DisconnectAndReconnect(i); break; // WRITING_STATE: // The request was successfully read from the client. // Get the reply data and write it to the client. case WRITING_STATE: GetAnswerToRequest(&Pipe[i]); fSuccess = WriteFile( Pipe[i].hPipeInst, Pipe[i].chReply, Pipe[i].cbToWrite, &cbRet, &Pipe[i].oOverlap); // The write operation completed successfully. if (fSuccess && cbRet == Pipe[i].cbToWrite) { Pipe[i].fPendingIO = FALSE; Pipe[i].dwState = READING_STATE; continue; } // The write operation is still pending. dwErr = GetLastError(); if (! fSuccess && (dwErr == ERROR_IO_PENDING)) { Pipe[i].fPendingIO = TRUE; continue; } // An error occurred; disconnect from the client. DisconnectAndReconnect(i); break; default: { printf("Invalid pipe state.\n"); return 0; } } } return 0; } // DisconnectAndReconnect(DWORD) // This function is called when an error occurs or when the client // closes its handle to the pipe. Disconnect from this client, then // call ConnectNamedPipe to wait for another client to connect. VOID DisconnectAndReconnect(DWORD i) { // Disconnect the pipe instance. if (! DisconnectNamedPipe(Pipe[i].hPipeInst) ) { printf("DisconnectNamedPipe failed with %d.\n", GetLastError()); } // Call a subroutine to connect to the new client. Pipe[i].fPendingIO = ConnectToNewClient( Pipe[i].hPipeInst, &Pipe[i].oOverlap); Pipe[i].dwState = Pipe[i].fPendingIO ? CONNECTING_STATE : // still connecting READING_STATE; // ready to read } // ConnectToNewClient(HANDLE, LPOVERLAPPED) // This function is called to start an overlapped connect operation. // It returns TRUE if an operation is pending or FALSE if the // connection has been completed. BOOL ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo) { BOOL fConnected, fPendingIO = FALSE; // Start an overlapped connection for this pipe instance. fConnected = ConnectNamedPipe(hPipe, lpo); // Overlapped ConnectNamedPipe should return zero. if (fConnected) { printf("ConnectNamedPipe failed with %d.\n", GetLastError()); return 0; } switch (GetLastError()) { // The overlapped connection in progress. case ERROR_IO_PENDING: fPendingIO = TRUE; break; // Client is already connected, so signal an event. case ERROR_PIPE_CONNECTED: if (SetEvent(lpo->hEvent)) break; // If an error occurs during the connect operation... default: { printf("ConnectNamedPipe failed with %d.\n", GetLastError()); return 0; } } return fPendingIO; }VOID GetAnswerToRequest(LPPIPEINST pipe){ _tprintf( TEXT("[%d] %s\n"), pipe->hPipeInst, pipe->chRequest); StringCchCopy( pipe->chReply, BUFSIZE, TEXT("Default answer from server") ); pipe->cbToWrite = (lstrlen(pipe->chReply)+1)*sizeof(TCHAR);}
完成例程命名管道服务器 Named Pipe Server Using Completion Routines
#include <windows.h> #include <stdio.h>#include <tchar.h>#include <strsafe.h>#define PIPE_TIMEOUT 5000#define BUFSIZE 4096 typedef struct { OVERLAPPED oOverlap; HANDLE hPipeInst; TCHAR chRequest[BUFSIZE]; DWORD cbRead; TCHAR chReply[BUFSIZE]; DWORD cbToWrite; } PIPEINST, *LPPIPEINST; VOID DisconnectAndClose(LPPIPEINST); BOOL CreateAndConnectInstance(LPOVERLAPPED); BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED); VOID GetAnswerToRequest(LPPIPEINST); VOID WINAPI CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED); VOID WINAPI CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED); HANDLE hPipe; int _tmain(VOID) { HANDLE hConnectEvent; OVERLAPPED oConnect; LPPIPEINST lpPipeInst; DWORD dwWait, cbRet; BOOL fSuccess, fPendingIO; // Create one event object for the connect operation. hConnectEvent = CreateEvent( NULL, // default security attribute TRUE, // manual reset event TRUE, // initial state = signaled NULL); // unnamed event object if (hConnectEvent == NULL) { printf("CreateEvent failed with %d.\n", GetLastError()); return 0; } oConnect.hEvent = hConnectEvent; // Call a subroutine to create one instance, and wait for // the client to connect. fPendingIO = CreateAndConnectInstance(&oConnect); while (1) { // Wait for a client to connect, or for a read or write // operation to be completed, which causes a completion // routine to be queued for execution. dwWait = WaitForSingleObjectEx( hConnectEvent, // event object to wait for INFINITE, // waits indefinitely TRUE); // alertable wait enabled switch (dwWait) { // The wait conditions are satisfied by a completed connect // operation. case 0: // If an operation is pending, get the result of the // connect operation. if (fPendingIO) { fSuccess = GetOverlappedResult( hPipe, // pipe handle &oConnect, // OVERLAPPED structure &cbRet, // bytes transferred FALSE); // does not wait if (!fSuccess) { printf("ConnectNamedPipe (%d)\n", GetLastError()); return 0; } } // Allocate storage for this instance. lpPipeInst = (LPPIPEINST) GlobalAlloc( GPTR, sizeof(PIPEINST)); if (lpPipeInst == NULL) { printf("GlobalAlloc failed (%d)\n", GetLastError()); return 0; } lpPipeInst->hPipeInst = hPipe; // Start the read operation for this client. // Note that this same routine is later used as a // completion routine after a write operation. lpPipeInst->cbToWrite = 0; CompletedWriteRoutine(0, 0, (LPOVERLAPPED) lpPipeInst); // Create new pipe instance for the next client. fPendingIO = CreateAndConnectInstance( &oConnect); break; // The wait is satisfied by a completed read or write // operation. This allows the system to execute the // completion routine. case WAIT_IO_COMPLETION: break; // An error occurred in the wait function. default: { printf("WaitForSingleObjectEx (%d)\n", GetLastError()); return 0; } } } return 0; } // CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED) // This routine is called as a completion routine after writing to // the pipe, or when a new client has connected to a pipe instance.// It starts another read operation. VOID WINAPI CompletedWriteRoutine(DWORD dwErr, DWORD cbWritten, LPOVERLAPPED lpOverLap) { LPPIPEINST lpPipeInst; BOOL fRead = FALSE; // lpOverlap points to storage for this instance. lpPipeInst = (LPPIPEINST) lpOverLap; // The write operation has finished, so read the next request (if // there is no error). if ((dwErr == 0) && (cbWritten == lpPipeInst->cbToWrite)) fRead = ReadFileEx( lpPipeInst->hPipeInst, lpPipeInst->chRequest, BUFSIZE*sizeof(TCHAR), (LPOVERLAPPED) lpPipeInst, (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedReadRoutine); // Disconnect if an error occurred. if (! fRead) DisconnectAndClose(lpPipeInst); } // CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED) // This routine is called as an I/O completion routine after reading // a request from the client. It gets data and writes it to the pipe. VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED lpOverLap) { LPPIPEINST lpPipeInst; BOOL fWrite = FALSE; // lpOverlap points to storage for this instance. lpPipeInst = (LPPIPEINST) lpOverLap; // The read operation has finished, so write a response (if no // error occurred). if ((dwErr == 0) && (cbBytesRead != 0)) { GetAnswerToRequest(lpPipeInst); fWrite = WriteFileEx( lpPipeInst->hPipeInst, lpPipeInst->chReply, lpPipeInst->cbToWrite, (LPOVERLAPPED) lpPipeInst, (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedWriteRoutine); } // Disconnect if an error occurred. if (! fWrite) DisconnectAndClose(lpPipeInst); } // DisconnectAndClose(LPPIPEINST) // This routine is called when an error occurs or the client closes // its handle to the pipe. VOID DisconnectAndClose(LPPIPEINST lpPipeInst) { // Disconnect the pipe instance. if (! DisconnectNamedPipe(lpPipeInst->hPipeInst) ) { printf("DisconnectNamedPipe failed with %d.\n", GetLastError()); } // Close the handle to the pipe instance. CloseHandle(lpPipeInst->hPipeInst); // Release the storage for the pipe instance. if (lpPipeInst != NULL) GlobalFree(lpPipeInst); } // CreateAndConnectInstance(LPOVERLAPPED) // This function creates a pipe instance and connects to the client. // It returns TRUE if the connect operation is pending, and FALSE if // the connection has been completed. BOOL CreateAndConnectInstance(LPOVERLAPPED lpoOverlap) { LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); hPipe = CreateNamedPipe( lpszPipename, // pipe name PIPE_ACCESS_DUPLEX | // read/write access FILE_FLAG_OVERLAPPED, // overlapped mode PIPE_TYPE_MESSAGE | // message-type pipe PIPE_READMODE_MESSAGE | // message read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // unlimited instances BUFSIZE*sizeof(TCHAR), // output buffer size BUFSIZE*sizeof(TCHAR), // input buffer size PIPE_TIMEOUT, // client time-out NULL); // default security attributes if (hPipe == INVALID_HANDLE_VALUE) { printf("CreateNamedPipe failed with %d.\n", GetLastError()); return 0; } // Call a subroutine to connect to the new client. return ConnectToNewClient(hPipe, lpoOverlap); }BOOL ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo) { BOOL fConnected, fPendingIO = FALSE; // Start an overlapped connection for this pipe instance. fConnected = ConnectNamedPipe(hPipe, lpo); // Overlapped ConnectNamedPipe should return zero. if (fConnected) { printf("ConnectNamedPipe failed with %d.\n", GetLastError()); return 0; } switch (GetLastError()) { // The overlapped connection in progress. case ERROR_IO_PENDING: fPendingIO = TRUE; break; // Client is already connected, so signal an event. case ERROR_PIPE_CONNECTED: if (SetEvent(lpo->hEvent)) break; // If an error occurs during the connect operation... default: { printf("ConnectNamedPipe failed with %d.\n", GetLastError()); return 0; } } return fPendingIO; }VOID GetAnswerToRequest(LPPIPEINST pipe){ _tprintf( TEXT("[%d] %s\n"), pipe->hPipeInst, pipe->chRequest); StringCchCopy( pipe->chReply, BUFSIZE, TEXT("Default answer from server") ); pipe->cbToWrite = (lstrlen(pipe->chReply)+1)*sizeof(TCHAR);}
命名管道客户端 Named Pipe Client
#include <windows.h> #include <stdio.h>#include <conio.h>#include <tchar.h>#define BUFSIZE 512 int _tmain(int argc, TCHAR *argv[]) { HANDLE hPipe; LPTSTR lpvMessage=TEXT("Default message from client"); TCHAR chBuf[BUFSIZE]; BOOL fSuccess; DWORD cbRead, cbWritten, dwMode; LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); if( argc > 1 ) lpvMessage = argv[1]; // Try to open a named pipe; wait for it, if necessary. while (1) { hPipe = CreateFile( lpszPipename, // pipe name GENERIC_READ | // read and write access GENERIC_WRITE, 0, // no sharing NULL, // default security attributes OPEN_EXISTING, // opens existing pipe 0, // default attributes NULL); // no template file // Break if the pipe handle is valid. if (hPipe != INVALID_HANDLE_VALUE) break; // Exit if an error other than ERROR_PIPE_BUSY occurs. if (GetLastError() != ERROR_PIPE_BUSY) { printf("Could not open pipe"); return 0; } // All pipe instances are busy, so wait for 20 seconds. if (!WaitNamedPipe(lpszPipename, 20000)) { printf("Could not open pipe"); return 0; } } // The pipe connected; change to message-read mode. dwMode = PIPE_READMODE_MESSAGE; fSuccess = SetNamedPipeHandleState( hPipe, // pipe handle &dwMode, // new pipe mode NULL, // don't set maximum bytes NULL); // don't set maximum time if (!fSuccess) { printf("SetNamedPipeHandleState failed"); return 0; } // Send a message to the pipe server. fSuccess = WriteFile( hPipe, // pipe handle lpvMessage, // message (lstrlen(lpvMessage)+1)*sizeof(TCHAR), // message length &cbWritten, // bytes written NULL); // not overlapped if (!fSuccess) { printf("WriteFile failed"); return 0; } do { // Read from the pipe. fSuccess = ReadFile( hPipe, // pipe handle chBuf, // buffer to receive reply BUFSIZE*sizeof(TCHAR), // size of buffer &cbRead, // number of bytes read NULL); // not overlapped if (! fSuccess && GetLastError() != ERROR_MORE_DATA) break; _tprintf( TEXT("%s\n"), chBuf ); } while (!fSuccess); // repeat loop if ERROR_MORE_DATA getch(); CloseHandle(hPipe); return 0; }
0 0
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- 命名管道
- iOS8中使用CoreLocation定位
- 在linux系统中安装MySQL
- Eclipse操作技巧
- orafce extension for PostgreSQL, Oracle's compatibility functions and packages
- Manacher-字符串处理
- 命名管道
- excel选定行变色
- 比较靠谱的修改MySQL编码的方法
- sharedpreference的用法与理解
- 九度OJ 1001:A+B for Matrices
- pat1046Shortest Distance (20)
- 转载一:OSM-Web服务器(一) PostgreSql 配置以及osm2pgsql原始PBF数据导入
- PostgreSQL 在3D 数据内容管理中的应用
- java锁机制