命名管道

来源:互联网 发布: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
原创粉丝点击