织梦CMS - 轻松建站从此开始!

罗索

进程间通信方式[图]

jackyhwei 发布于 2011-05-25 17:18 点击:次 
跨网络的进程间通信可用:命名管道和邮槽(邮槽可实现一对多通信)邮槽发送的数据量较小,发送大量数据可采用管道来完成
TAG:

一 利用剪贴板进行进程间通信

void CClipboardDlg::OnBtnSend()
{
// TODO: Add your control notification handler code here
if(OpenClipboard())    //打开剪贴板
{
   EmptyClipboard();   //释放剪贴板中数据的句柄并分配剪贴板所有权给当前窗口

   CString str;
   HANDLE hClip;
   char *pBuf;
   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();       //关闭剪贴板
}
}

void CClipboardDlg::OnBtnRecv()
{
// TODO: Add your control notification handler code here
if(OpenClipboard())
{
   if(IsClipboardFormatAvailable(CF_TEXT))   //检测剪贴板是否包含指定格式的数据
   {
    HANDLE hClip;
    hClip=GetClipboardData(CF_TEXT);   //从剪贴板中获取指定格式的数据
    char *pBuf;
    pBuf=(char*)GlobalLock(hClip);    //将句柄转换为地址
    GlobalUnlock(hClip);
    SetDlgItemText(IDC_EDIT_RECV,pBuf);
    CloseClipboard();
   }
}
}

二 利用匿名管道进行进程间通信(匿名管道只能在父子进程间通信)

父进程

void CParentView::OnPipeCreate()
{
// TODO: 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;
ZeroMemory(&sui,sizeof(STARTUPINFO));
sui.cb=sizeof(STARTUPINFO);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);

PROCESS_INFORMATION pi;

if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,
   TRUE,0,NULL,NULL,&sui,&pi))
{
  CloseHandle(hRead);
   CloseHandle(hWrite);
   hRead=NULL;
   hWrite=NULL;
   MessageBox("创建子进程失败!");
   return;
}
else
{
   CloseHandle(pi.hProcess);
   CloseHandle(pi.hThread);
}
}

void CParentView::OnPipeRead()
{
// TODO: 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()
{
// TODO: Add your command handler code here
char buf[]="武汉科技大学黄家湖校区";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
   MessageBox("写入数据失败!");
   return;
}
}

子进程

void CChildView::OnInitialUpdate()
{
CView::OnInitialUpdate();

// TODO: Add your specialized code here and/or call the base class
hRead=GetStdHandle(STD_INPUT_HANDLE);
hWrite=GetStdHandle(STD_OUTPUT_HANDLE);
}

void CChildView::OnPipeRead()
{
// TODO: 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()
{
// TODO: Add your command handler code here
char buf[]="匿名管道测试程序";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
   MessageBox("写入数据失败!");
   return;
}
}

三 利用命名管道进行进程间通信

服务端进程

void CNamedPipeSrvView::OnPipeCreate()
{
// TODO: 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()
{
// TODO: 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()
{
// TODO: Add your command handler code here
char buf[]="武汉科技大学黄家湖校区";
DWORD dwWrite;
if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))
{
   MessageBox("写入数据失败!");
   return;
}
}

客户端进程

void CNamedPipeCltView::OnPipeConnect()
{
// TODO: 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()
{
// TODO: 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()
{
// TODO: Add your command handler code here
char buf[]="命名管道测试程序";
DWORD dwWrite;
if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))
{
   MessageBox("写入数据失败!");
   return;
}
}

四 利用邮槽进行进程间通信

 

服务端进程

void CMailslotSrvView::OnMailslotRecv()
{
// TODO: 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);
}

客户端进程

void CMailslotCltView::OnMailslotSend()
{
// TODO: 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[]="邮槽测试程序";
DWORD dwWrite;
if(!WriteFile(hMailslot,buf,strlen(buf)+1,&dwWrite,NULL)) //邮槽的客户端只能发送数据
{
   MessageBox("写入数据失败!");
   CloseHandle(hMailslot);
   return;
}
CloseHandle(hMailslot);
}

跨网络的进程间通信可用:命名管道和邮槽(邮槽可实现一对多通信)

邮槽发送的数据量较小,发送大量数据可采用管道来完成

(studyarea)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201105/12959.html]
本文出处:百度博客 作者:studyarea
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容