32位Windows采用虚拟内存技术使每个进程虚拟4G内存,在逻辑上实现了对进程之间数据代码的分离与保护。那么相应的进程之间的通信也就有必要整理掌握一下。
Windows进程间通讯的方法有很多:管道、邮件槽、剪切板、共享内存、消息、套接字、RPC、DDE等。
但是他们大部分拥有一个共同的本质:利用Windows操作系统高2GB内核共享空间进行数据传递的桥梁,所以他们都是内核对象!
所以他们大部分都要遵循:A创建对象-->A写入数据-->B打开A创建的对象-->B读入数据的规则
下面着重通过一些代码Demo来加深下对进程间通信的理解
0X01
命名管道
进程A代码
#define READ_PIPE L"\\\\.\\pipe\\ReadPipe" #define WRITE_PIPE L"\\\\.\\pipe\\WritePipe" // 管道命名 typedef struct _USER_CONTEXT_ { HANDLE hPipe; HANDLE hEvent; }USER_CONTEXT,*PUSER_CONTEXT; USER_CONTEXT Context[2] = {0}; HANDLE hThread[2] = {0}; BOOL WritePipe(); BOOL ReadPipe(); BOOL bOk = FALSE; DWORD WINAPI WritePipeThread(LPVOID LPParam); DWORD WINAPI ReadPipeThread(LPVOID LPParam); int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; HANDLE hPipe = NULL; if (WritePipe()==FALSE) { return -1; } if (ReadPipe()==FALSE) { return -1; } int iIndex = 0; while (TRUE) { if (bOk==TRUE) { SetEvent(Context[0].hEvent); SetEvent(Context[1].hEvent); Sleep(1); } iIndex = WaitForMultipleObjects(2,hThread,TRUE,5000); if (iIndex==WAIT_TIMEOUT) { continue; } else { break; } } int i = 0; for (i=0;i<2;i++) { CloseHandle(Context[i].hEvent); CloseHandle(Context[i].hPipe); } CloseHandle(hThread[0]); CloseHandle(hThread[1]); cout<<"Exit"<<endl; return nRetCode; } BOOL WritePipe() { HANDLE hWritePipe = NULL; hWritePipe = CreateNamedPipe( WRITE_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, MAX_PATH, MAX_PATH, 0, NULL); if (hWritePipe==INVALID_HANDLE_VALUE) { return FALSE; } HANDLE hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); Context[0].hEvent = hEvent; Context[0].hPipe = hWritePipe; hThread[0] = CreateThread(NULL,0,WritePipeThread,NULL,0,NULL); return TRUE; } BOOL ReadPipe() { HANDLE hReadPipe = NULL; hReadPipe = CreateNamedPipe( READ_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, MAX_PATH, MAX_PATH, 0, NULL); if (hReadPipe==INVALID_HANDLE_VALUE) { return FALSE; } HANDLE hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); Context[1].hEvent = hEvent; Context[1].hPipe = hReadPipe; hThread[1] = CreateThread(NULL,0,ReadPipeThread,NULL,0,NULL); return TRUE; } DWORD WINAPI ReadPipeThread(LPVOID LPParam) { HANDLE hEvent = Context[1].hEvent; HANDLE hReadPipe = Context[1].hPipe; DWORD dwReturn = 0; char szBuffer[MAX_PATH] = {0}; int iIndex = 0; while (TRUE) { iIndex = WaitForSingleObject(hEvent,30); iIndex = iIndex-WAIT_OBJECT_0; if (iIndex==WAIT_FAILED||iIndex==0) { break; } if (ReadFile(hReadPipe,szBuffer,MAX_PATH,&dwReturn,NULL)) { szBuffer[dwReturn] = '\0'; cout<<szBuffer<<endl; } else { if (GetLastError()==ERROR_INVALID_HANDLE) { break; } } } return 0; } DWORD WINAPI WritePipeThread(LPVOID LPParam) { HANDLE hEvent = Context[0].hEvent; HANDLE hWritePipe = Context[0].hPipe; DWORD dwReturn = 0; char szBuffer[MAX_PATH] = {0}; int iIndex = 0; while (TRUE) { iIndex = WaitForSingleObject(hEvent,30); iIndex = iIndex-WAIT_OBJECT_0; if (iIndex==WAIT_FAILED||iIndex==0) { break; } cin>>szBuffer; if (WriteFile(hWritePipe,szBuffer,strlen(szBuffer),&dwReturn,NULL)) { } else { if (GetLastError()==ERROR_INVALID_HANDLE) { break; } } } return 0; }