C++进程通信之命名管道

来源:互联网 发布:数据库工程师培训机构 编辑:程序博客网 时间:2024/06/05 11:08

命名管道通过网络来完成进程间通信,它屏蔽了底层的网络协议细节。

采用命名管道完成进程通信的过程为:

1.在服务器端调用CreateNamedPipe创建命名管道之后,调用ConnectNamedPipe函数让服务器进程等待客户端进程连接到该命名管道的实例上。

2.在客户端,首先调用WaitNamedPipe函数判断当前是否有可以利用的命名管道实例,如果有就调用CreateFile函数打开该命名管道的实例,并建立一个连接。

之后就可以通过ReadFile、WriteFile进行通信。


一、服务器端程序

private:HANDLE     m_hPipe;//命名管道实例句柄

void CNamedPipeSrcView::OnPipeCreate(){//创建命名管道m_hPipe = CreateNamedPipe("\\\\.\\pipe\\MyPipe",PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, 0, 1, 1024, 1024, 0, NULL);if (INVALID_HANDLE_VALUE == m_hPipe){MessageBox("创建命名管道失败!");m_hPipe = NULL;return;}//创建匿名的人工重置事件对象HANDLE hEvent;hEvent = CreateEvent(NULL, TRUE, FALSE,NULL);if (!hEvent){MessageBox("创建事件对象失败");CloseHandle(m_hPipe);m_hPipe = NULL;return;}OVERLAPPED ovlap;ZeroMemory(&ovlap, sizeof(OVERLAPPED));ovlap.hEvent = hEvent;//等待客户端请求的到来if (!ConnectNamedPipe(m_hPipe, &ovlap)){if (ERROR_IO_PENDING != GetLastError()){MessageBox("等待客户端连接失败!");CloseHandle(m_hPipe);CloseHandle(hEvent);m_hPipe = NULL;return;}}if (WAIT_FAILED == WaitForSingleObject(hEvent, INFINITE)){MessageBox("等待事件对象失败!");CloseHandle(m_hPipe);CloseHandle(hEvent);m_hPipe = NULL;return;}CloseHandle(hEvent);//执行到这一步,说明已经有客户端连上命名管道实例,不再需要该事件对象句柄}void CNamedPipeSrcView::OnPipeRead(){char buf[100];DWORD dwRead;if (!ReadFile(m_hPipe, buf, 100, &dwRead, NULL)){MessageBox("读取数据失败!");return;}MessageBox(buf);}void CNamedPipeSrcView::OnPipeWrite(){char buf[]="dadadadakai";DWORD dwWrite;if (!WriteFile(m_hPipe, buf, strlen(buf)+1, &dwWrite, NULL)){MessageBox("写入数据失败!");return;}}


二、客户端程序

private:HANDLE  m_hPipe;//命名管道实例句柄

void CNamedPipeClientView::OnPipeConnect(){//判断是否有可以利用的命名管道if (!WaitNamedPipe("\\\\.\\pipe\\MyPipe", //如果是跨网络通信,则在圆点处指定服务器端程序所在的主机名NMPWAIT_USE_DEFAULT_WAIT)){MessageBox("当前没有可以利用的命名管道实例!");return;}//打开可用的命名管道,并与服务器端进程进行通信m_hPipe = CreateFile("\\\\.\\pipe\\MyPipe",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (INVALID_HANDLE_VALUE == m_hPipe){MessageBox("打开命名管道失败!");m_hPipe = NULL;return;}}void CNamedPipeClientView::OnPipeRead(){char buf[100];  DWORD dwRead;  if (!ReadFile(m_hPipe,buf,100,&dwRead,NULL))//利用命名管道读取数据  {  MessageBox("读取数据失败!");  return;  }  else  {  MessageBox(buf);  }  }void CNamedPipeClientView::OnPipeWrite(){char buf[]="yyyyyyyxue";  DWORD dwWrite;  if (!WriteFile(m_hPipe,buf,strlen(buf)+1, &dwWrite, NULL))//利用命名管道写入数据  {  MessageBox("写入数据失败!");  return;  }  }



0 0
原创粉丝点击