首页 > 代码库 > 命名管道-MSDN例子
命名管道-MSDN例子
服务器:
1 #include "stdafx.h" 2 #include <windows.h> 3 #include <stdio.h> 4 #include <tchar.h> 5 #include <strsafe.h> 6 7 #define BUFSIZE 512 8 9 DWORD WINAPI InstanceThread(LPVOID); 10 VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD); 11 12 int _tmain(VOID) 13 { 14 BOOL fConnected = FALSE; 15 DWORD dwThreadId = 0; 16 HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL; 17 LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); 18 19 // The main loop creates an instance of the named pipe and 20 // then waits for a client to connect to it. When the client 21 // connects, a thread is created to handle communications 22 // with that client, and this loop is free to wait for the 23 // next client connect request. It is an infinite loop. 24 25 for (;;) 26 { 27 _tprintf( TEXT("\nPipe Server: Main thread awaiting client connection on %s\n"), lpszPipename); 28 hPipe = CreateNamedPipe( 29 lpszPipename, // pipe name 30 PIPE_ACCESS_DUPLEX, // read/write access 31 PIPE_TYPE_MESSAGE | // message type pipe 32 PIPE_READMODE_MESSAGE | // message-read mode 33 PIPE_WAIT, // blocking mode 34 PIPE_UNLIMITED_INSTANCES, // max. instances 35 BUFSIZE, // output buffer size 36 BUFSIZE, // input buffer size 37 0, // client time-out 38 NULL); // default security attribute 39 40 if (hPipe == INVALID_HANDLE_VALUE) 41 { 42 _tprintf(TEXT("CreateNamedPipe failed, GLE=%d.\n"), GetLastError()); 43 return -1; 44 } 45 46 // Wait for the client to connect; if it succeeds, 47 // the function returns a nonzero value. If the function 48 // returns zero, GetLastError returns ERROR_PIPE_CONNECTED. 49 50 //等待客户端接入(目前为阻塞模式) 51 fConnected = ConnectNamedPipe(hPipe, NULL) ? 52 TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 53 54 if (fConnected) 55 { 56 printf("Client connected, creating a processing thread.\n"); 57 58 // Create a thread for this client. 59 hThread = CreateThread( 60 NULL, // no security attribute 61 0, // default stack size 62 InstanceThread, // thread proc 63 (LPVOID) hPipe, // thread parameter 64 0, // not suspended 65 &dwThreadId); // returns thread ID 66 67 if (hThread == NULL) 68 { 69 _tprintf(TEXT("CreateThread failed, GLE=%d.\n"), GetLastError()); 70 return -1; 71 } 72 else CloseHandle(hThread); 73 } 74 else 75 // The client could not connect, so close the pipe. 76 CloseHandle(hPipe); 77 78 } 79 80 return 0; 81 } 82 83 DWORD WINAPI InstanceThread(LPVOID lpvParam) 84 // This routine is a thread processing function to read from and reply to a client 85 // via the open pipe connection passed from the main loop. Note this allows 86 // the main loop to continue executing, potentially creating more threads of 87 // of this procedure to run concurrently, depending on the number of incoming 88 // client connections. 89 { 90 HANDLE hHeap = GetProcessHeap(); 91 TCHAR* pchRequest = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR)); 92 TCHAR* pchReply = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR)); 93 94 DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0; 95 BOOL fSuccess = FALSE; 96 HANDLE hPipe = NULL; 97 98 // Do some extra error checking since the app will keep running even if this 99 // thread fails. 100 101 if (lpvParam == NULL) 102 { 103 printf( "\nERROR - Pipe Server Failure:\n"); 104 printf( " InstanceThread got an unexpected NULL value in lpvParam.\n"); 105 printf( " InstanceThread exitting.\n"); 106 if (pchReply != NULL) HeapFree(hHeap, 0, pchReply); 107 if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest); 108 return (DWORD)-1; 109 } 110 111 if (pchRequest == NULL) 112 { 113 printf( "\nERROR - Pipe Server Failure:\n"); 114 printf( " InstanceThread got an unexpected NULL heap allocation.\n"); 115 printf( " InstanceThread exitting.\n"); 116 if (pchReply != NULL) HeapFree(hHeap, 0, pchReply); 117 return (DWORD)-1; 118 } 119 120 if (pchReply == NULL) 121 { 122 printf( "\nERROR - Pipe Server Failure:\n"); 123 printf( " InstanceThread got an unexpected NULL heap allocation.\n"); 124 printf( " InstanceThread exitting.\n"); 125 if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest); 126 return (DWORD)-1; 127 } 128 129 // Print verbose messages. In production code, this should be for debugging only. 130 printf("InstanceThread created, receiving and processing messages.\n"); 131 132 // The thread‘s parameter is a handle to a pipe object instance. 133 134 hPipe = (HANDLE) lpvParam; 135 136 // Loop until done reading 137 while (1) 138 { 139 // Read client requests from the pipe. This simplistic code only allows messages 140 // up to BUFSIZE characters in length. 141 fSuccess = ReadFile( 142 hPipe, // handle to pipe 143 pchRequest, // buffer to receive data 144 BUFSIZE*sizeof(TCHAR), // size of buffer 145 &cbBytesRead, // number of bytes read 146 NULL); // not overlapped I/O 147 148 if (!fSuccess || cbBytesRead == 0) 149 { 150 if (GetLastError() == ERROR_BROKEN_PIPE) 151 { 152 _tprintf(TEXT("InstanceThread: client disconnected.\n"), GetLastError()); 153 } 154 else 155 { 156 _tprintf(TEXT("InstanceThread ReadFile failed, GLE=%d.\n"), GetLastError()); 157 } 158 break; 159 } 160 161 // Process the incoming message. 162 GetAnswerToRequest(pchRequest, pchReply, &cbReplyBytes); 163 164 // Write the reply to the pipe. 165 fSuccess = WriteFile( 166 hPipe, // handle to pipe 167 pchReply, // buffer to write from 168 cbReplyBytes, // number of bytes to write 169 &cbWritten, // number of bytes written 170 NULL); // not overlapped I/O 171 172 if (!fSuccess || cbReplyBytes != cbWritten) 173 { 174 _tprintf(TEXT("InstanceThread WriteFile failed, GLE=%d.\n"), GetLastError()); 175 break; 176 } 177 } 178 179 // Flush the pipe to allow the client to read the pipe‘s contents 180 // before disconnecting. Then disconnect the pipe, and close the 181 // handle to this pipe instance. 182 183 FlushFileBuffers(hPipe); 184 DisconnectNamedPipe(hPipe); 185 CloseHandle(hPipe); 186 187 HeapFree(hHeap, 0, pchRequest); 188 HeapFree(hHeap, 0, pchReply); 189 190 printf("InstanceThread exitting.\n"); 191 return 1; 192 } 193 194 VOID GetAnswerToRequest( LPTSTR pchRequest, 195 LPTSTR pchReply, 196 LPDWORD pchBytes ) 197 // This routine is a simple function to print the client request to the console 198 // and populate the reply buffer with a default data string. This is where you 199 // would put the actual client request processing code that runs in the context 200 // of an instance thread. Keep in mind the main thread will continue to wait for 201 // and receive other client connections while the instance thread is working. 202 { 203 _tprintf( TEXT("Client Request String:\"%S\"\n"), pchRequest );//这里注意大小写的%S,见上一篇随笔 204 205 // Check the outgoing message to make sure it‘s not too long for the buffer. 206 if (FAILED(StringCchCopy( pchReply, BUFSIZE, TEXT("default answer from server") ))) 207 { 208 *pchBytes = 0; 209 pchReply[0] = 0; 210 printf("StringCchCopy failed, no outgoing message.\n"); 211 return; 212 } 213 *pchBytes = (lstrlen(pchReply)+1)*sizeof(TCHAR); 214 }
客户端:
// client.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #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 = FALSE; DWORD cbRead, cbToWrite, 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) { _tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() ); return -1; } // All pipe instances are busy, so wait for 20 seconds. if ( ! WaitNamedPipe(lpszPipename, 20000)) { printf("Could not open pipe: 20 second wait timed out."); return -1; } } // 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) { _tprintf( TEXT("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() ); return -1; } // Send a message to the pipe server. cbToWrite = (lstrlen(lpvMessage)+1)*sizeof(TCHAR); _tprintf( TEXT("Sending %d byte message: \"%s\"\n"), cbToWrite, lpvMessage); fSuccess = WriteFile( hPipe, // pipe handle lpvMessage, // message cbToWrite, // message length &cbWritten, // bytes written NULL); // not overlapped if ( ! fSuccess) { _tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError() ); return -1; } printf("\nMessage sent to server, receiving reply as follows:\n"); 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 if ( ! fSuccess) { _tprintf( TEXT("ReadFile from pipe failed. GLE=%d\n"), GetLastError() ); return -1; } printf("\n<End of message, press ENTER to terminate connection and exit>"); _getch(); CloseHandle(hPipe); return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。