vc++17 进程间的通信
来源:互联网 发布:淘宝物流查询 编辑:程序博客网 时间:2024/04/29 12:23
进程间的通信模式:
①、剪贴板
建立一个APPWIZARD,然后创建2个按钮(发送,接收),2个编辑框,
对按钮添加函数;
void CClickDlg::OnButtonSend() {//打开剪贴板,保存信息于剪贴板上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();}}void CClickDlg::OnButtonRecv() {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();}}②,通过管道同步消息
创建匿名管道:
1建立单文档appwizard之pipe,添加三个菜单,“创建匿名管道,读取data,写入data”
2添加句柄hread hwrite,
3添加相应菜单“创建匿名管道”的菜单函数
void CPipeView::OnPipeCreate() {SECURITY_ATTRIBUTES sa;sa.bInheritHandle=TRUE;sa.lpSecurityDescriptor=NULL;sa.nLength=sizeof(SECURITY_ATTRIBUTES);if(!CreatePipe(&hRead,&hWrite,&sa,0)){MessageBox("创建匿名管道失败");return ;}//启动子进程,交给读写选项;STARTUPINFO stinfo;//memset(&stinfo,0,sizeof(STARTUPINFO));ZeroMemory(&stinfo,sizeof(STARTUPINFO));//对所用到的结构成员赋值stinfo.cb=sizeof(STARTUPINFO);stinfo.dwFlags=STARTF_USESTDHANDLES;//结构体,标准输入\出句柄有效stinfo.hStdInput=hRead;stinfo.hStdOutput=hWrite;//将进程的标准入\出句柄设置为管道的读写句柄stinfo.hStdError=GetStdHandle(STD_ERROR_HANDLE);//获得父进程的标准错误句柄;//进程消息的指针LPPROCESS_INFORMATION定义PROCESS_INFORMATION pl;if(!CreateProcess("E:\\vc6.0\\MSDev98\\MyProjects\\test\\child\\child\\Debug\\child.exe",NULL,NULL,NULL,TRUE,0,NULL,NULL,&stinfo,&pl))//创建一个子线程,实现通过管道进行子进程和父进程的通信;{CloseHandle(hRead);CloseHandle(hWrite);hRead=NULL;hWrite=NULL;MessageBox("创建子进程失败");return;}else{CloseHandle(pl.hProcess);//将内核对象计数器减 1,为0是收回你内核对象的内存CloseHandle(pl.hThread);}}重要的是两个函数,一个是Createpipe()和另一个CreateProecess()函数;
3、添加“读取数据”函数响应
void CPipeView::OnPipeRead() {char buf[100]={0};DWORD dwRead;//保存实际读取的字节数;if(!ReadFile(hRead,buf,100,&dwRead,NULL)){MessageBox("读取失败");return;}MessageBox(buf);}4 添加“读取数据”函数响应
void CPipeView::OnPipeWrite() {char buf[]="this is my test pipe";DWORD dwWrite;if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL)){MessageBox("写入失败");return;}}5编写关于 子进程Child的实现,同样的创建一个appwizard 单文档,命名为“child”,然后添加菜单,“接收data”和“发送data”
6.添加句柄 hread和hwrite 以保存表示输入和输出句柄;
7添加关于View类里面的onnitialUpdate的虚函数,并在这个里面获得标准输入\出句柄;
void CChildView::OnInitialUpdate() {CView::OnInitialUpdate();//获得标准的读写句柄hRead=GetStdHandle(STD_INPUT_HANDLE);hWrite=GetStdHandle(STD_OUTPUT_HANDLE);}
8添加Child的菜单的“接收data”和“发送Data”的函数
void CChildView::OnPipeWrite() {char buf[]="匿名管道测试";DWORD dwWrite;if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))//WriteFile()读写管道{MessageBox("写入失败");return;}}void CChildView::OnPipeRead() {char buf[100]={0};DWORD dwRead;//保存实际读取的字节数;if(!ReadFile(hRead,buf,100,&dwRead,NULL))//ReadFile,读管道消息{MessageBox("读取失败");return;}MessageBox(buf);}
运行父进程“创建匿名管道”,启动子进程,便可以进行进程之间的通信;
利用命名管道
匿名管道只能在父子子进程进行通信,而.命名管道:还可以跨网络通信,服务器只能在win2000和NT下运行!而客户端可以在95下运行。关键函数CreateNamedPipe
创建一个基于命名管道的进程通信例子
服务器端部分
1.添加一个句柄变量来保存一个命名管道的实例句柄(View类里面)
2.添加“创建命名管道的响应函数”
//创建一个句柄变量来保存一个命名管道的实例句柄void CNamedPipeView::OnPipreCreate() {hPipe=CreateNamedPipe("\\\\.\\pipe\\mypipe",PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,0,1,1024,1024,0,NULL);if (INVALID_HANDLE_VALUE==hPipe){MessageBox("创建命名管道失败");return;}HANDLE hEvent;hEvent=CreateEvent(NULL,TRUE,TRUE,NULL);if (!hEvent){MessageBox("创建时间失败");return;}OVERLAPPED owlap;memset(&owlap,0,sizeof(owlap));owlap.hEvent=hEvent;if(!ConnectNamedPipe(hPipe,&owlap)){if (ERROR_IO_PENDING!=GetLastError())//此处返回值如果是ERROR_IO_PENDING不表示错误,而是稍后可能继续执行{MessageBox("等待客户端连接失败!");CloseHandle(hPipe);CloseHandle(hEvent);hPipe=NULL;return;}if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE)){MessageBox("等待对象失败");return;}CloseHandle(hEvent);}}3,添加发送和接收部分的函数
void CNamedPipeView::OnEditWrite() {// TODO: Add your command handler code herechar buf[]="服务器端写入:匿名管道测试";DWORD dwWrite;if(!WriteFile(hPipe,buf,strlen(buf)+1,&dwWrite,NULL))//WriteFile()读写管道{MessageBox("服务器端写入失败");return;}}void CNamedPipeView::OnEditRead() {char buf[100]={0};DWORD dwRead;//保存实际读取的字节数;if(!ReadFile(hPipe,buf,100,&dwRead,NULL))//ReadFile,读管道消息{MessageBox("服务器端读取失败");return;}MessageBox(buf);}客户端部分的程序:
1,同服务器端部分的第一二部分
2.建立“连接管道的函数”
void CNamedPipeCotView::OnPipeConnect() {// 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 (hpipe==INVALID_HANDLE_VALUE){MessageBox("打开命名管道失败");hpipe=NULL;return;}}3,建立接收和发送的函数
void CNamedPipeCotView::OnPipeRead() {char buf[100]={0};DWORD dwRead;//保存实际读取的字节数;if(!ReadFile(hpipe,buf,100,&dwRead,NULL))//ReadFile,读管道消息{MessageBox("客户端读取失败");return;}MessageBox(buf);}void CNamedPipeCotView::OnPipeWrite() {char buf[]="客户端写入:匿名管道测试";DWORD dwWrite;if(!WriteFile(hpipe,buf,strlen(buf)+1,&dwWrite,NULL))//WriteFile()读写管道{MessageBox("客户端写入失败");return;} }
四、通过邮槽来实现进程间通信;
邮槽是一种单向传送机制;邮槽是基于广播的,可以一对多发送。但只能一个发送,一个接收,要想同时发送接收,须写两次代码。
服务器端部分:创建邮槽,准备接收数据
void CMailSlotSrvView::OnMailslotRecv() {HANDLE HMailSlot;HMailSlot=CreateMailslot("\\\\.\\mailslot\\MyMailSlot",0,MAILSLOT_WAIT_FOREVER,NULL);if (INVALID_HANDLE_VALUE==HMailSlot){MessageBox("创建油槽失败");HMailSlot=NULL;return;}//创建成功,接收数据,因为服务器端只能接收数据;char buf[100]={0};DWORD dwRead;//保存实际读取的字节数;if(!ReadFile(HMailSlot,buf,100,&dwRead,NULL))//ReadFile,读管道消息{MessageBox("客户端读取失败");CloseHandle(HMailSlot);return;}MessageBox(buf);CloseHandle(HMailSlot);}
建立客户端发送数据部分:
void CMailSlotClientView::OnMailslotSend() {HANDLE hMailSlotClient;hMailSlotClient=CreateFile("\\\\.\\mailslot\\MyMailSlot",GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//打开油槽;if (INVALID_HANDLE_VALUE==hMailSlotClient){MessageBox("打开油槽失败");hMailSlotClient=NULL;return;}//打开油槽写入数据;char buf[]="客户端写入:匿名管道测试";DWORD dwWrite;if(!WriteFile(hMailSlotClient,buf,strlen(buf)+1,&dwWrite,NULL))//WriteFile()读写管道{MessageBox("客户端写入失败");CloseHandle(hMailSlotClient);return;}CloseHandle(hMailSlotClient);}
- vc++17 进程间的通信
- VC 进程间通信
- VC:进程间通信
- VC:进程间通信
- VC 进程间通信
- VC 进程间通信
- vc进程间通信
- 孙鑫VC++第17章进程间的通信
- vc++中进程间的通信
- vc++中进程间的通信
- VC++中进程间相互通信的十一种方法
- VC++中进程间相互通信的十一种方法
- VC++中进程间通信的十一种方法
- VC++中进程间相互通信的十一种方法
- VC++中进程间相互通信的多种方法
- VC++中进程间相互通信的十一种方法
- VC++中进程间相互通信的十一种方法
- VC++进程间相互通信的十一种方法
- 我的大学生活
- C++表达式求值的顺序
- 企业邮箱那点事儿(五):企业邮箱问题集锦
- Failed to load JavaHL Library.
- delphi中提示Microsoft Jet 4.0 OLE DB Provider坏了提示未安装什么的
- vc++17 进程间的通信
- 各种钱币拼接造型
- 良好的编程风格
- 不能将参数1从“const char []”转换为“LPCTSTR
- ios中上下左右滑动的各种手势
- nginx windows 下安装和配置
- C语言中__attribute__的作用
- 死锁的四个必要条件及处理死锁
- 第七周任务-星号图