孙鑫vc++ 17 进程间通信(3) 命名管道

来源:互联网 发布:windows更新组策略 编辑:程序博客网 时间:2024/05/22 14:09

一、基础知识

1.命名管道

(1)命名管道是围绕Windows文件系统设计的一种机制,采用“‘命名管道文件系统’(Named Pipe File System,NPFS)“接口

(2)命名管道通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节;命名管道不仅可以在本机上实现两个进程间的通信,还可以跨网络实现两个进程间的通信

(3)命名管道分为客户端和服务器,两者的区别在于:服务器是唯一有权创建命名管道的进程,只有他才能接受管道客户端的请求;同时,对同一个命名管道的实例来说,在某一时刻,他只能和一个客户端进行通信

(4)命名管道提供了两种基本通信模式:字节模式和消息模式;

(5)字节模式:数据以一个连续的字节流的形式在客户机和服务器之间流动

(6)消息模式:客户机和服务器通过一系列不连续的数据单位,进行数据的收发,每次管道上发出了一个消息后,他必须作为完整的信息读入

(7)在采用命名管道进行通信的两个进程之间,不需要有任何的关系,可以独立的启动这两个进程

二、从代码进行分析

1.服务器进程//创建命名管道void CNamedPipSrvView::OnCreatePipe(){ // TODO: Add your command handler code here hPipe = CreateNamedPipe(_T("\\\\.\\pipe\\MyPipe"),  PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,  0,  1,  1024,  1024,  0,  NULL); if (INVALID_HANDLE_VALUE == hPipe) {  MessageBox(_T("管道创建失败!"));  hPipe = NULL;  return; } HANDLE hEvent; hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); OVERLAPPED ovlap; ZeroMemory(&ovlap,sizeof(ovlap)); ovlap.hEvent = hEvent; if (!ConnectNamedPipe(hPipe,&ovlap)) {  if (ERROR_IO_PENDING != GetLastError())  {   MessageBox(_T("等待客户连接失败!"));   CloseHandle(hEvent);   CloseHandle(hPipe);   hPipe = NULL;   return;  }  } if (WAIT_FAILED == WaitForSingleObject(hEvent,INFINITE)) {  MessageBox(_T("等待事件对象失败!"));  CloseHandle(hEvent);  CloseHandle(hPipe);  hPipe = NULL;  return; } CloseHandle(hEvent); } //向管道写入数据void CNamedPipSrvView::OnWrite(){ // TODO: Add your command handler code here char buf[] = "服务器进程写入的数据"; DWORD dwWrite; if (!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL)) {  ::MessageBox(m_hWnd,_T("写入数据失败!"),NULL,MB_OK);  return; }} //从管道读取数据void CNamedPipSrvView::OnRead(){ // TODO: Add your command handler code here char buf[100]; DWORD dwRead; if (!ReadFile(hPipe,buf,100,&dwRead,NULL)) {  ::MessageBox(m_hWnd,_T("读取数据失败!"),NULL,MB_OK);  return; } ::MessageBox(m_hWnd,(LPCTSTR)buf,NULL,MB_OK);}2.客户端进程//连接管道void CNamedPipCltView::OnOpen(){ // TODO: Add your command handler code here if (!WaitNamedPipe(_T("\\\\.\\pipe\\MyPipe"),NMPWAIT_WAIT_FOREVER)) {  MessageBox(_T("当前没有可利用的命名管道!"));  return; } hPipe = CreateFile(_T("\\\\.\\pipe\\MyPipe"),  GENERIC_READ | GENERIC_WRITE,  0,  NULL,  OPEN_EXISTING,  FILE_ATTRIBUTE_NORMAL,  NULL); if (INVALID_HANDLE_VALUE == hPipe) {  MessageBox(_T("打开命名管道失败!"));  hPipe = NULL;  return; }} //向管道写入数据void CNamedPipCltView::OnWrite(){ // TODO: Add your command handler code here char buf[] = "客户端进程写入的数据"; DWORD dwWrite; if (!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL)) {  ::MessageBox(m_hWnd,_T("写入数据失败!"),NULL,MB_OK);  return; }} //从管道读取数据void CNamedPipCltView::OnRead(){ // TODO: Add your command handler code here char buf[100]; DWORD dwRead; if (!ReadFile(hPipe,buf,100,&dwRead,NULL)) {  ::MessageBox(m_hWnd,_T("读取数据失败!"),NULL,MB_OK);  return; } ::MessageBox(m_hWnd,(LPCTSTR)buf,NULL,MB_OK);}

3.需要掌握的函数

(1)CreateNamedPipe

(2)CreateEvent

(3)GetLastError

(4)ConnectNamedPipe

(5)WaitForSingleObject

(6)CreateFile

 

 

原创粉丝点击