命名管道通过网络来完成进程间通信,它屏蔽了底层的网络协议细节。
采用命名管道完成进程通信的过程为:
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)
站点信息
- 文章2313
- 用户1336
- 访客11745763
每日一句
Light follows every storm.
风暴后总有光。
风暴后总有光。
jQuery打造漂亮的幻灯片效果
Linux查看进程及相关操作常用命令
解决安卓运行错误Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug
华为:你硬要打压,我偏要强大!
thinkpad t470p装黑苹果系统10.13.2
Android常用的数学函数说明
Android Studio使用DB Browser查看SQLite数据库
使用Putty上传文件?
关于IDEA的Spring boot项目创建慢,Maven插件加载慢,依赖导入慢或者失败的原因及解决方案
imencode和imdecode使用
element-UI组件实现拖拽效果
【教程】手把手教你开通淘小铺赚佣金
Android简单树状实现
新会员