MFC(进程间的通信,孙鑫C++第十七讲笔记整理)

来源:互联网 发布:高德导航车载端口修改 编辑:程序博客网 时间:2024/06/07 18:01

有四种方法

1.剪贴板

a.创建个ClipBoard的对话框应用程序,加两EditBox和两个Button发送接收。

b.具体代码:

   发送端代码:

if(OpenClipboard())

{

CString str;

HANDLE hClip;

char *pBuf;

EmptyClipboard();

GetDlgItemText(IDC_EDIT_SEND,str);

hClip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);

pBuf=(char*)GlobalLock(hClip);将句柄转换为指针!

strcpy(pBuf,str);

GlobalUnlock(hClip);

SetClipboardData(CF_TEXT,hClip);

CloseClipboard();

}

    接收端代码:

if(OpenClipboard())

{

if(IsClipboardFormatAvailable(CF_TEXT))

{

  HANDLE hClip;

  char *pBuf;

  hClip=GetClipboardData(CF_TEXT);

  pBuf=(char*)GlobalLock(hClip);

  GlobalUnlock(hClip);

  SetDlgItemText(IDC_EDIT_RECV,pBuf);

  CloseClipboard();

}

}

2.匿名管道:只能在父子进程之间进行通信

a.先建一个Parent的单文档应用程序,增加“创建管道”“读取数据”“写入数据”三个菜单

b.增加成员变量HANDLE类型的hRead,hWrite,初始化变量,并在析构函数中释放句柄

c.响应菜单代码:

void CParentView::OnPipeCreate()菜单“创建管道”代码

{

// TOD Add your command handler code here

SECURITY_ATTRIBUTES sa;

sa.bInheritHandle=TRUE;

sa.lpSecurityDescriptor=NULL;

sa.nLength=sizeof(SECURITY_ATTRIBUTES);

if(!CreatePipe(&hRead,&hWrite,&sa,0))

{

MessageBox("创建匿名管道失败!");

return;

}

STARTUPINFO sui;

PROCESS_INFORMATION pi;

ZeroMemory(&sui,sizeof(STARTUPINFO));将数据清0!

sui.cb=sizeof(STARTUPINFO);

sui.dwFlags=STARTF_USESTDHANDLES;

sui.hStdInput=hRead;

sui.hStdOutput=hWrite;

sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);

if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,

  TRUE,0,NULL,NULL,&sui,&pi))创建子进程

{

CloseHandle(hRead);

CloseHandle(hWrite);关闭句柄,将内核对象的使用计数减少1,这样当操作系统发现内核对象的使用计数为0时,将清除内核对象。

hRead=NULL;

hWrite=NULL;

MessageBox("创建子进程失败!");

return;

}

else

{

CloseHandle(pi.hProcess);

CloseHandle(pi.hThread);

}

}void CParentView::OnPipeRead()菜单“读取数据”代码

{

// TOD Add your command handler code here

char buf[100];

DWORD dwRead;

if(!ReadFile(hRead,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

return;

}

MessageBox(buf);

}void CParentView::OnPipeWrite()菜单“写入数据”代码

{

// TOD Add your command handler code here

char buf[]="http://www.sunxin.org";

DWORD dwWrite;

if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

return;

}

}

d.再建一个Child的单文档,在View中增加两个成员hRead和hWrite.在OnInitialUpdate()中得到句柄的值。

void CChildView::OnInitialUpdate()

{

CView::OnInitialUpdate();

// TOD Add your specialized code here and/or call the base class

hRead=GetStdHandle(STD_INPUT_HANDLE);注意这句代码!

hWrite=GetStdHandle(STD_OUTPUT_HANDLE);

}    e.加菜单“读取数据”“写入数据”其代码如下:

void CChildView::OnPipeRead()

{

// TOD Add your command handler code here

char buf[100];

DWORD dwRead;

if(!ReadFile(hRead,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

return;

}

MessageBox(buf);

}void CChildView::OnPipeWrite()

{

// TOD Add your command handler code here

char buf[]="匿名管道测试程序";

DWORD dwWrite;

if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

return;

}

}

3.命名管道:还可以跨网络通信,服务器只能在win2000和NT下运行!而客户端可以在95下运行。关键函数CreateNamedPipe

a.先建一个NamedPipeSRV单文档应用程序,加菜单“创建管道”“读取数据”“写入数据”

b.在View中增加Handle变量hPipe,注意在析构函数中释放它!

c.响应菜单,创建命名管道

void CNamedPipeSrvView::OnPipeCreate()

{

// TOD Add your command handler code here

hPipe=CreateNamedPipe("\\\\.\\pipe\\MyPipe",

PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,

0,1,1024,1024,0,NULL);

if(INVALID_HANDLE_VALUE==hPipe)

{

MessageBox("创建命名管道失败!");

hPipe=NULL;

return;

}

HANDLE hEvent;

hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

if(!hEvent)

{

MessageBox("创建事件对象失败!");

CloseHandle(hPipe);

hPipe=NULL;

return;

}

OVERLAPPED ovlap;

ZeroMemory(&ovlap,sizeof(OVERLAPPED));

ovlap.hEvent=hEvent;

if(!ConnectNamedPipe(hPipe,&ovlap))

{

if(ERROR_IO_PENDING!=GetLastError())

{

  MessageBox("等待客户端连接失败!");

  CloseHandle(hPipe);

  CloseHandle(hEvent);

  hPipe=NULL;

  return;

}

}

if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE))

{

MessageBox("等待对象失败!");

CloseHandle(hPipe);

CloseHandle(hEvent);

hPipe=NULL;

return;

}

CloseHandle(hEvent);

}void CNamedPipeSrvView::OnPipeRead()

{

// TOD Add your command handler code here

char buf[100];

DWORD dwRead;

if(!ReadFile(hPipe,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

return;

}

MessageBox(buf);

}void CNamedPipeSrvView::OnPipeWrite()

{

// TOD Add your command handler code here

char buf[]="http://www.sunxin.org";

DWORD dwWrite;

if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

return;

}

}     d.再建一个NamedPipeCLT单文档工程,加菜单“连接管道”“读取数据”“写入数据”,当然别忘记成员变量hPipe的定义和初始化

     e.响应菜单代码

void CNamedPipeCltView::OnPipeConnect()连接管道

{

// TOD Add your command handler code here

if(!WaitNamedPipe("\\\\.\\pipe\\MyPipe",NMPWAIT_WAIT_FOREVER))

{

MessageBox("当前没有可利用的命名管道实例!");

return;

}

hPipe=CreateFile("\\\\.\\pipe\\MyPipe",GENERIC_READ | GENERIC_WRITE,

0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(INVALID_HANDLE_VALUE==hPipe)

{

MessageBox("打开命名管道失败!");

hPipe=NULL;

return;

}

}void CNamedPipeCltView::OnPipeRead()读取数据

{

// TOD Add your command handler code here

char buf[100];

DWORD dwRead;

if(!ReadFile(hPipe,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

return;

}

MessageBox(buf);

}void CNamedPipeCltView::OnPipeWrite()写入数据

{

// TOD Add your command handler code here

char buf[]="命名管道测试程序";

DWORD dwWrite;

if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

return;

}

}

4.邮槽,使用时应将消息长度限制在424字节以下,关键函数CreateMailSlot()

a.先建一个MailSlotSRV工程,加菜单“接收数据”

b.消息响应代码:

void CMailslotSrvView::OnMailslotRecv()菜单“接收数据”的代码

{

// TOD Add your command handler code here

HANDLE hMailslot;

hMailslot=CreateMailslot("\\\\.\\mailslot\\MyMailslot",0,

MAILSLOT_WAIT_FOREVER,NULL);

if(INVALID_HANDLE_VALUE==hMailslot)

{

MessageBox("创建油槽失败!");

return;

}

char buf[100];

DWORD dwRead;

if(!ReadFile(hMailslot,buf,100,&dwRead,NULL))

{

MessageBox("读取数据失败!");

CloseHandle(hMailslot);

return;

}

MessageBox(buf);

CloseHandle(hMailslot);

}

   c.加工程MailSlotCLT,加菜单“发送数据”

   d.加消息响应,添加代码,客户端也比较简单。

void CMailslotCltView::OnMailslotSend()菜单“发送数据”的代码

{

// TOD Add your command handler code here

HANDLE hMailslot;

hMailslot=CreateFile("\\\\.\\mailslot\\MyMailslot",GENERIC_WRITE,

FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(INVALID_HANDLE_VALUE==hMailslot)

{

MessageBox("打开油槽失败!");

return;

}

char buf[]="http://www.sunxin.org";

DWORD dwWrite;

if(!WriteFile(hMailslot,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

CloseHandle(hMailslot);

return;

}

CloseHandle(hMailslot);

}

5.以上4种方法各有优缺点:剪贴板比较简单。邮槽是基于广播的,可以一对多发送。但只能一个发送,一个接收,要想同时发送接收,须写两次代码。

命名管道和邮槽可以进行网络通信。

剪切板

[cpp] view plaincopyprint?
  1. void CJieQieBanDlg::OnSend()  
  2.     // TODO: Add your control notification handler code here 
  3.  
  4.     if(OpenClipboard())//首先要打开剪切板 
  5.     { 
  6.         CString str; 
  7.         HANDLE hChip; 
  8.         char *pBuf; 
  9.  
  10.         EmptyClipboard();//清空剪切板 
  11.         GetDlgItemText(ID_FASONG,str);//获取发送数据的内容 
  12. hChip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//分配空间,返回一个句柄
  13.  
  14.         pBuf=(char*)GlobalLock(hChip);//上锁,返回一个字符指针 
  15.         strcpy(pBuf,str);//复制内容 
  16.         GlobalUnlock(hChip);//解锁 
  17.  
  18.         SetClipboardData(CF_TEXT,hChip);//设置剪切板的内容 
  19.  
  20.         CloseClipboard(); 
  21.     } 
  22.      
void CJieQieBanDlg::OnSend() {// TODO: Add your control notification handler code hereif(OpenClipboard())//首先要打开剪切板{CString str;HANDLE hChip;char *pBuf;EmptyClipboard();//清空剪切板GetDlgItemText(ID_FASONG,str);//获取发送数据的内容hChip=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//分配空间,返回一个句柄pBuf=(char*)GlobalLock(hChip);//上锁,返回一个字符指针strcpy(pBuf,str);//复制内容GlobalUnlock(hChip);//解锁SetClipboardData(CF_TEXT,hChip);//设置剪切板的内容CloseClipboard();}}


[cpp] view plaincopyprint?
  1. void CJieQieBanDlg::OnRecv()  
  2.     // TODO: Add your control notification handler code here 
  3.      
  4.     if(OpenClipboard())//打开剪切板 
  5.     { 
  6.         if(IsClipboardFormatAvailable(CF_TEXT))//判断剪切板的内容格式是否是我们需要的 
  7.         { 
  8.             HANDLE hChip; 
  9.             char *pBuf; 
  10.             hChip=GetClipboardData(CF_TEXT);//返回一个句柄 
  11.             pBuf=(char*)GlobalLock(hChip);//获取内容 
  12.             GlobalUnlock(hChip); 
  13.             SetDlgItemText(ID_JIESHOU,pBuf);//设置内容 
  14.             CloseHandle(hChip); 
  15.  
  16.  
  17.         } 
  18.     } 
  19.  
void CJieQieBanDlg::OnRecv() {// TODO: Add your control notification handler code hereif(OpenClipboard())//打开剪切板{if(IsClipboardFormatAvailable(CF_TEXT))//判断剪切板的内容格式是否是我们需要的{HANDLE hChip;char *pBuf;hChip=GetClipboardData(CF_TEXT);//返回一个句柄pBuf=(char*)GlobalLock(hChip);//获取内容GlobalUnlock(hChip);SetDlgItemText(ID_JIESHOU,pBuf);//设置内容CloseHandle(hChip);}}}


匿名管道:

1父进程:

a添加两个CXXView成员变量HANDLE hRead,HANDLE hWrite

b构造函数赋值hRead=NULL,hWrite=NULL,析构函数if(!hRead) CloseHandle(hRead)...

c

[cpp] view plaincopyprint?
  1. void CParentView::OnPipeCreate()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     SECURITY_ATTRIBUTES  sa; 
  5.     sa.bInheritHandle=TRUE; 
  6.     sa.lpSecurityDescriptor=NULL; 
  7.     sa.nLength=sizeof(SECURITY_ATTRIBUTES); 
  8.  
  9.     if(!CreatePipe(&hRead,&hWrite,&sa,0)) 
  10.     { 
  11.         MessageBox("创建管道失败"); 
  12.         return ; 
  13.     } 
  14.  
  15.     PROCESS_INFORMATION  pi; 
  16.      
  17.     STARTUPINFO sui; 
  18.     ZeroMemory(&sui,sizeof(STARTUPINFO));//这一句很重要,将数据清零 
  19.     sui.cb=sizeof(STARTUPINFO); 
  20.     sui.dwFlags=STARTF_USESTDHANDLES; 
  21.     sui.hStdInput=hRead; 
  22.     sui.hStdOutput=hWrite; 
  23.     sui.hStdError=GetStdHandle(STD_ERROR_HANDLE); 
  24.  
  25.     if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi)) 
  26.     { 
  27.         CloseHandle(hWrite); 
  28.         CloseHandle(hRead); 
  29.         hRead=NULL; 
  30.         hWrite=NULL; 
  31.         MessageBox("子进程创建失败"); 
  32.         return ; 
  33.     } 
  34.     else 
  35.     { 
  36.         CloseHandle(pi.hProcess); 
  37.         CloseHandle(pi.hThread); 
  38.     } 
  39.  
  40.  
  41.      
void CParentView::OnPipeCreate() {// TODO: Add your command handler code hereSECURITY_ATTRIBUTES  sa;sa.bInheritHandle=TRUE;sa.lpSecurityDescriptor=NULL;sa.nLength=sizeof(SECURITY_ATTRIBUTES);if(!CreatePipe(&hRead,&hWrite,&sa,0)){MessageBox("创建管道失败");return ;}PROCESS_INFORMATION  pi;STARTUPINFO sui;ZeroMemory(&sui,sizeof(STARTUPINFO));//这一句很重要,将数据清零sui.cb=sizeof(STARTUPINFO);sui.dwFlags=STARTF_USESTDHANDLES;sui.hStdInput=hRead;sui.hStdOutput=hWrite;sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&sui,&pi)){CloseHandle(hWrite);CloseHandle(hRead);hRead=NULL;hWrite=NULL;MessageBox("子进程创建失败");return ;}else{CloseHandle(pi.hProcess);CloseHandle(pi.hThread);}}



d

[cpp] view plaincopyprint?
  1. void CParentView::OnXieru()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     char temp[]="hello,i am writing..."; 
  5.      
  6.     unsigned long len; 
  7.     if(!WriteFile(hWrite,temp,strlen(temp)+1,&len,NULL)) 
  8.     { 
  9.         MessageBox("写入失败"); 
  10.         return ; 
  11.     } 
  12.  
  13.  
  14.      
void CParentView::OnXieru() {// TODO: Add your command handler code herechar temp[]="hello,i am writing...";unsigned long len;if(!WriteFile(hWrite,temp,strlen(temp)+1,&len,NULL)){MessageBox("写入失败");return ;}}


e

[cpp] view plaincopyprint?
  1. void CParentView::OnDuqu()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     char temp[100]; 
  5.     unsigned long len; 
  6.  
  7.     if(!ReadFile(hRead,temp,100,&len,NULL)) 
  8.     { 
  9.         MessageBox("读取失败"); 
  10.         return ; 
  11.     } 
  12.  
  13.     MessageBox(temp); 
  14.  
  15.      
void CParentView::OnDuqu() {// TODO: Add your command handler code herechar temp[100];unsigned long len;if(!ReadFile(hRead,temp,100,&len,NULL)){MessageBox("读取失败");return ;}MessageBox(temp);}


子进程
a,CXXVIEW中添加成员变量HANDLE hRead,HANDLE hWrite,在构造函数和析构函数进行响应的操作

bCXXView中添加虚函数OnInitialUpdate

[cpp] view plaincopyprint?
  1. void CChildView::OnInitialUpdate()  
  2.     CView::OnInitialUpdate(); 
  3.      
  4.     // TODO: Add your specialized code here and/or call the base class 
  5.  
  6.     hRead=GetStdHandle(STD_INPUT_HANDLE); 
  7.     hWrite=GetStdHandle(STD_OUTPUT_HANDLE); 
  8.      
void CChildView::OnInitialUpdate() {CView::OnInitialUpdate();// TODO: Add your specialized code here and/or call the base classhRead=GetStdHandle(STD_INPUT_HANDLE);hWrite=GetStdHandle(STD_OUTPUT_HANDLE);}


[cpp] view plaincopyprint?
  1. void CChildView::OnXieru()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     char temp[]="hello,wel to my blog,i am afei"; 
  5.     unsigned long len; 
  6.     if(!WriteFile(hWrite,temp,strlen(temp)+1,&len,NULL)) 
  7.     { 
  8.         MessageBox("写入数据失败"); 
  9.         return ; 
  10.     } 
  11.      
void CChildView::OnXieru() {// TODO: Add your command handler code herechar temp[]="hello,wel to my blog,i am afei";unsigned long len;if(!WriteFile(hWrite,temp,strlen(temp)+1,&len,NULL)){MessageBox("写入数据失败");return ;}}


[cpp] view plaincopyprint?
  1. void CChildView::OnDuqu()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     char temp[100]; 
  5.     unsigned long len; 
  6.  
  7.     if(!ReadFile(hRead,temp,100,&len,NULL)) 
  8.     { 
  9.         MessageBox("读取数据失败"); 
  10.         return ; 
  11.     } 
  12.     MessageBox(temp); 
  13.      
void CChildView::OnDuqu() {// TODO: Add your command handler code herechar temp[100];unsigned long len;if(!ReadFile(hRead,temp,100,&len,NULL)){MessageBox("读取数据失败");return ;}MessageBox(temp);}


先启动父进程,然后通过父进程建立子进程,然后就能实现父子进程之间的通信了。

命名管道:(可跨网络)

1服务器端:

a,CXXView中添加成员变量HANDLE hPipe

b,

[cpp] view plaincopyprint?
  1. void CNamePipeSerView::OnPipeCreate()  
  2.     // TODO: Add your command handler code here 
  3.      
  4.     hPipe=CreateNamedPipe("\\\\.\\pipe\\mypipe",PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED, 
  5.                 0,1,1024,1024,0,NULL);//要转义 
  6.  
  7.     if(INVALID_HANDLE_VALUE==hPipe) 
  8.     { 
  9.         MessageBox("命名管道创建失败"); 
  10.         hPipe=NULL; 
  11.         return ; 
  12.     } 
  13.  
  14.     HANDLE hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); 
  15.     if(!hEvent) 
  16.     { 
  17.         MessageBox("对象事件创建失败"); 
  18.         return ; 
  19.     } 
  20.  
  21.     OVERLAPPED oa; 
  22.     ZeroMemory(&oa,sizeof(OVERLAPPED)); 
  23.     oa.hEvent=hEvent; 
  24.     if(!ConnectNamedPipe(hPipe,&oa)) 
  25.     { 
  26.         if(ERROR_IO_PENDING!=GetLastError()) 
  27.         { 
  28.  
  29.          
  30.         MessageBox("命名管道连接失败"); 
  31.         CloseHandle(hEvent); 
  32.         CloseHandle(hPipe); 
  33.         hEvent=NULL; 
  34.         hPipe=NULL; 
  35.  
  36.         return ; 
  37.         } 
  38.     } 
  39.  
  40.     if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE)) 
  41.     { 
  42.         MessageBox("对象等待失败"); 
  43.         CloseHandle(hEvent); 
  44.         CloseHandle(hPipe); 
  45.         hEvent=NULL; 
  46.         hPipe=NULL; 
  47.         return ; 
  48.     } 
  49.  
void CNamePipeSerView::OnPipeCreate() {// TODO: Add your command handler code herehPipe=CreateNamedPipe("\\\\.\\pipe\\mypipe",PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,0,1,1024,1024,0,NULL);//要转义if(INVALID_HANDLE_VALUE==hPipe){MessageBox("命名管道创建失败");hPipe=NULL;return ;}HANDLE hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);if(!hEvent){MessageBox("对象事件创建失败");return ;}OVERLAPPED oa;ZeroMemory(&oa,sizeof(OVERLAPPED));oa.hEvent=hEvent;if(!ConnectNamedPipe(hPipe,&oa)){if(ERROR_IO_PENDING!=GetLastError()){MessageBox("命名管道连接失败");CloseHandle(hEvent);CloseHandle(hPipe);hEvent=NULL;hPipe=NULL;return ;}}if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE)){MessageBox("对象等待失败");CloseHandle(hEvent);CloseHandle(hPipe);hEvent=NULL;hPipe=NULL;return ;}}


[cpp] view plaincopyprint?
  1. void CNamePipeSerView::OnXieru()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     char temp[]="hello,i am afei"; 
  5.      
  6.     unsigned long len; 
  7.     if(!WriteFile(hPipe,temp,strlen(temp)+1,&len,NULL)) 
  8.     { 
  9.         MessageBox("写入文件失败"); 
  10.         return ; 
  11.     } 
  12.  
  13.      
void CNamePipeSerView::OnXieru() {// TODO: Add your command handler code herechar temp[]="hello,i am afei";unsigned long len;if(!WriteFile(hPipe,temp,strlen(temp)+1,&len,NULL)){MessageBox("写入文件失败");return ;}}


[cpp] view plaincopyprint?
  1. void CNamePipeSerView::OnDuqu()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     char temp[100]; 
  5.      
  6.     unsigned long len; 
  7.     if(!ReadFile(hPipe,temp,100,&len,NULL)) 
  8.     { 
  9.         MessageBox("读取文件失败"); 
  10.         return ; 
  11.     } 
  12.      
  13.     MessageBox(temp); 
  14.      
void CNamePipeSerView::OnDuqu() {// TODO: Add your command handler code herechar temp[100];unsigned long len;if(!ReadFile(hPipe,temp,100,&len,NULL)){MessageBox("读取文件失败");return ;}MessageBox(temp);}


客户端:

[cpp] view plaincopyprint?
  1. void CNamePipeCliView::OnLianjie()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     if(!WaitNamedPipe("\\\\.\\pipe\\mypipe",NMPWAIT_WAIT_FOREVER)) 
  5.     { 
  6.         MessageBox("没有可用的命名管道实例"); 
  7.         return ; 
  8.     } 
  9.  
  10.     hPipe=CreateFile("\\\\.\\pipe\\mypipe",GENERIC_READ|GENERIC_WRITE,0,NULL, 
  11.         OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 
  12.  
  13.     if(INVALID_HANDLE_VALUE==hPipe) 
  14.     { 
  15.         MessageBox("打开管道失败"); 
  16.         hPipe=NULL; 
  17.         return ; 
  18.     } 
  19.  
  20.  
  21.      
void CNamePipeCliView::OnLianjie() {// TODO: Add your command handler code hereif(!WaitNamedPipe("\\\\.\\pipe\\mypipe",NMPWAIT_WAIT_FOREVER)){MessageBox("没有可用的命名管道实例");return ;}hPipe=CreateFile("\\\\.\\pipe\\mypipe",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if(INVALID_HANDLE_VALUE==hPipe){MessageBox("打开管道失败");hPipe=NULL;return ;}}


[cpp] view plaincopyprint?
  1. void CNamePipeCliView::OnXieru()  
  2.     // TODO: Add your command handler code here 
  3.      
  4.     char temp[]="i love C++,MFC..."; 
  5.     unsigned long len; 
  6.     if(!WriteFile(hPipe,temp,strlen(temp)+1,&len,NULL)) 
  7.     { 
  8.  
  9.         MessageBox("写入文件失败"); 
  10.  
  11.         return ; 
  12.     } 
  13.  
  14.      
void CNamePipeCliView::OnXieru() {// TODO: Add your command handler code herechar temp[]="i love C++,MFC...";unsigned long len;if(!WriteFile(hPipe,temp,strlen(temp)+1,&len,NULL)){MessageBox("写入文件失败");return ;}}


[cpp] view plaincopyprint?
  1. void CNamePipeCliView::OnDuqu()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     char temp[100]; 
  5.  
  6.     unsigned long len; 
  7.     if(!ReadFile(hPipe,temp,100,&len,NULL)) 
  8.     { 
  9.         MessageBox("读取文件失败"); 
  10.         return ; 
  11.     } 
  12.  
  13.     MessageBox(temp); 
  14.      
void CNamePipeCliView::OnDuqu() {// TODO: Add your command handler code herechar temp[100];unsigned long len;if(!ReadFile(hPipe,temp,100,&len,NULL)){MessageBox("读取文件失败");return ;}MessageBox(temp);}


这样就可以实现两个进程之间的通信了,

邮槽:(一对多)

1服务器端(接收数据)

[cpp] view plaincopyprint?
  1. void CYouCaoSerView::OnJieshou()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     HANDLE hMail; 
  5.     hMail=CreateMailslot("\\\\.\\mailslot\\mymail",0,MAILSLOT_WAIT_FOREVER,NULL); 
  6.  
  7.     if(INVALID_HANDLE_VALUE==hMail) 
  8.     { 
  9.         MessageBox("创建油槽失败"); 
  10.         return ; 
  11.     } 
  12.  
  13.     char temp[200]; 
  14.     DWORD dwlen; 
  15.     if(!ReadFile(hMail,temp,200,&dwlen,NULL)) 
  16.     { 
  17.         CloseHandle(hMail); 
  18.         MessageBox("读取失败"); 
  19.         return ; 
  20.     } 
  21.     CloseHandle(hMail); 
  22.     MessageBox(temp); 
  23.  
  24.      
void CYouCaoSerView::OnJieshou() {// TODO: Add your command handler code hereHANDLE hMail;hMail=CreateMailslot("\\\\.\\mailslot\\mymail",0,MAILSLOT_WAIT_FOREVER,NULL);if(INVALID_HANDLE_VALUE==hMail){MessageBox("创建油槽失败");return ;}char temp[200];DWORD dwlen;if(!ReadFile(hMail,temp,200,&dwlen,NULL)){CloseHandle(hMail);MessageBox("读取失败");return ;}CloseHandle(hMail);MessageBox(temp);}


2客户端:(发送数据)

[cpp] view plaincopyprint?
  1. void CYouCaoCView::OnFasong()  
  2.     // TODO: Add your command handler code here 
  3.  
  4.     HANDLE hMail; 
  5.     hMail=CreateFile("\\\\.\\mailslot\\mymail",GENERIC_WRITE,FILE_SHARE_READ,NULL, 
  6.                     OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 
  7.  
  8.     if(INVALID_HANDLE_VALUE==hMail) 
  9.     { 
  10.         MessageBox("打开油槽失败"); 
  11.         return ; 
  12.     } 
  13.  
  14.     char temp[]="hello,welcome to my blog,i am afei"; 
  15.     DWORD dwlen; 
  16.     if(!WriteFile(hMail,temp,strlen(temp)+1,&dwlen,NULL)) 
  17.     { 
  18.         CloseHandle(hMail); 
  19.         MessageBox("写入数据失败"); 
  20.         return ; 
  21.     } 
  22.  
  23.     CloseHandle(hMail); 
  24.  
  25.      
void CYouCaoCView::OnFasong() {// TODO: Add your command handler code hereHANDLE hMail;hMail=CreateFile("\\\\.\\mailslot\\mymail",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if(INVALID_HANDLE_VALUE==hMail){MessageBox("打开油槽失败");return ;}char temp[]="hello,welcome to my blog,i am afei";DWORD dwlen;if(!WriteFile(hMail,temp,strlen(temp)+1,&dwlen,NULL)){CloseHandle(hMail);MessageBox("写入数据失败");return ;}CloseHandle(hMail);}


要先打开服务器端的接收消息,这样客户端的发送消息才能打开油槽

要实现可以发送又可以接收的油槽运用程序,可以在同一个程序中,既编写客户端又编写服务器

 

转自:http://blog.csdn.net/zh634455283/article/details/7897456

原创粉丝点击