命名管道通过网络来完成进程间通信,它屏蔽了底层的网络协议细节。
采用命名管道完成进程通信的过程为:
1.在服务器端调用CreateNamedPipe创建命名管道之后,调用ConnectNamedPipe函数让服务器进程等待客户端进程连接到该命名管道的实例上。
2.在客户端,首先调用WaitNamedPipe函数判断当前是否有可以利用的命名管道实例,如果有就调用CreateFile函数打开该命名管道的实例,并建立一个连接。
之后就可以通过ReadFile、WriteFile进行通信。
服务端
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; } }
客户端
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) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2306
- 用户1336
- 访客11546930
每日一句
Nurture passes nature.
教养胜过天性。
教养胜过天性。
Notepad++如何代码格式化——NppAStyle
wordpress采集器——Wp-AutoPost精简无限制版
iOS路径剪切和蒙版
Android模拟点击延迟解决方法
使用MyBatis_Generator生成Dto、Dao、Mapping
如何在2020年获得理想的工作-战略路线图!
关于IDEA的Spring boot项目创建慢,Maven插件加载慢,依赖导入慢或者失败的原因及解决方案
ndk神奇问题之non-numeric second argument to `wordlist' function: '8.7z'
Android Studio创建进程通信简单例子
软件测试教程:如何执行测试
Android Studio使用Eclipse的debug.keystore
ConstraintLayout布局初试之环形动画效果
Android实现六边形图像
新会员