标签:
通信流程:
注意:
CreateMailslot函数详解
函数原型:
HANDLE CreateMailslot( LPCTSTR lpName, // mailslot name DWORD nMaxMessageSize, // maximum message size DWORD lReadTimeout, // read time-out interval LPSECURITY_ATTRIBUTES lpSecurityAttributes // inheritance option );
参数说明:
代码样例:
服务器端源码:
#include<windows.h> #include<cstdlib> #include<iostream> using namespace std; void main() { HANDLE hMailslot; char buf[100]; DWORD dwRead; //创建邮槽 hMailslot=CreateMailslot("\\\\.\\mailslot\\Communication",0, MAILSLOT_WAIT_FOREVER,NULL); if(INVALID_HANDLE_VALUE==hMailslot) { cout<<"创建邮槽失败!"<<endl; system("pause"); return; } //等待用户写入数据然后读取出数据 if(!ReadFile(hMailslot,buf,100,&dwRead,NULL)) { cout<<"读取数据失败!"<<endl; CloseHandle(hMailslot); system("pause"); return; } cout<<buf<<endl; //关闭邮槽 CloseHandle(hMailslot); system("pause"); }
客户端源码:
#include<windows.h> #include<cstdlib> #include<iostream> using namespace std; void main() { HANDLE hMailslot; char buf[]="this is message"; //打开邮槽 hMailslot=CreateFile("\\\\.\\mailslot\\Communication",GENERIC_WRITE, FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(INVALID_HANDLE_VALUE==hMailslot) { cout<<"打开邮槽失败!"<<endl; system("pause"); return; } //向邮槽写数据 DWORD dwWrite; if(!WriteFile(hMailslot,buf,strlen(buf)+1,&dwWrite,NULL)) { cout<<"写入数据失败!"<<endl; CloseHandle(hMailslot); system("pause"); return; } //关闭邮槽 CloseHandle(hMailslot); system("pause"); }
运行结果(先运行服务器端程序,然后在运行客户端程序):
说明:
匿名管道是一个未命名的,单向管道,通常用来在一个父进程和一个子进程之间传输数据,匿名管道只能实现在本机上的两个进程通信,而不能实现跨网络的通信
通信过程
相关函数
CreatePipe 管道创建
函数原型
BOOL CreatePipe( PHANDLE hReadPipe, // pointer to read handle PHANDLE hWritePipe, // pointer to write handle LPSECURITY_ATTRIBUTES lpPipeAttributes, // pointer to security attributes DWORD nSize // pipe size );
参数说明:
返回值
若函数成功返回非零值
若函数失败返回0,详细消息可以调用GetLastError函数获得
代码样例:
工程目录结构:
匿名管道
|-- child
| `-- debug
| `-- child.exe
` -- parent
`-- debug
`-- parent.exe
父进程源码:
#include<windows.h> #include<iostream> #include<cstdlib> using namespace std; void main() { SECURITY_ATTRIBUTES sa; STARTUPINFO sui; PROCESS_INFORMATION pi; HANDLE hRead,hWrite; char rebuf[100]; DWORD dwRead; //创建匿名管道 sa.bInheritHandle=TRUE; sa.lpSecurityDescriptor=NULL; sa.nLength=sizeof(SECURITY_ATTRIBUTES); if(!CreatePipe(&hRead,&hWrite,&sa,0)) { cout<<"创建匿名管道失败!"<<endl; system("pause"); return; } //创建子进程并对相关子进程相关数据进行初始化 (用匿名管道的读取写入句柄赋予子进程的输入输出句柄) 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,CREATE_NEW_CONSOLE,NULL,NULL,&sui,&pi)) { cout<<"创建子进程失败!"<<endl; system("pause"); return; } else { //关闭子进程相关句柄(进行句柄,进程主线程句柄) CloseHandle(pi.hProcess); CloseHandle(pi.hThread); Sleep(2000); //读取数据 if(!ReadFile(hRead,rebuf,100,&dwRead,NULL)) { cout<<"读取数据失败!"<<endl; system("pause"); return; } cout<<rebuf<<endl; } system("pause"); }
子进程源码:
#include<windows.h> #include<iostream> #include<cstdlib> using namespace std; void main() { HANDLE hRead,hWrite; //获得匿名管道输入输出句柄 hRead=GetStdHandle(STD_INPUT_HANDLE); hWrite=GetStdHandle(STD_OUTPUT_HANDLE); char sebuf[]=" 子进程写入管道成功"; char rebuf[100]; DWORD dwWrite; //写入数据 if(!WriteFile(hWrite,sebuf,strlen(sebuf)+1,&dwWrite,NULL)) { cout<<"写入数据失败!"<<endl; system("pause"); return; } Sleep(500); system("pause"); }
作用
命名管道不仅可以实现在本机上两个进程间的通信,还可以跨网络实现两个进程间的通信
两种通信模式
通信流程
服务器:
#include<windows.h> #include<cstdlib> #include<iostream> using namespace std; void main() { HANDLE hPipe,hEvent;; DWORD dwRead,dwWrite; OVERLAPPED ovlap; char sebuf[]="this is sever!"; char rebuf[100]; /*创建命名连接*****************************************************/ hPipe=CreateNamedPipe("\\\\.\\pipe\\Communication", PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0,1,1024,1024,0,NULL); if(INVALID_HANDLE_VALUE==hPipe) { cout<<"创建命名管道失败!"<<endl; hPipe=NULL; system("pause"); return; } /*创建命名管道连接*************************************************/ hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); if(!hEvent) { cout<<"创建事件对象失败!"<<endl; CloseHandle(hPipe); hPipe=NULL; system("pause"); return; } ZeroMemory(&ovlap,sizeof(OVERLAPPED)); ovlap.hEvent=hEvent; //创建管道连接 if(!ConnectNamedPipe(hPipe,&ovlap)) { if(ERROR_IO_PENDING!=GetLastError()) { cout<<"等待客户端连接失败!"<<endl; CloseHandle(hPipe); CloseHandle(hEvent); hPipe=NULL; system("pause"); return; } } //等待客户端连接 if(WAIT_FAILED==WaitForSingleObject(hEvent,INFINITE)) { cout<<"等待对象失败!"<<endl; CloseHandle(hPipe); CloseHandle(hEvent); hPipe=NULL; system("pause"); return; } CloseHandle(hEvent); /*读写管道数据*****************************************************/ //写入数据 if(!ReadFile(hPipe,rebuf,100,&dwRead,NULL)) { cout<<"读取数据失败!"<<endl; system("pause"); return; } cout<<rebuf<<endl; //写入数据 if(!WriteFile(hPipe,sebuf,strlen(sebuf)+1,&dwWrite,NULL)) { cout<<"写入数据失败!"<<endl; system("pause"); return; } system("pause"); }
#include<windows.h> #include<cstdlib> #include<iostream> using namespace std; void main() { HANDLE hPipe; DWORD dwRead,dwWrite; char sebuf[]="this is client!"; char rebuf[100]; /*连接管道连接*****************************************************/ if(!WaitNamedPipe("\\\\.\\pipe\\Communication",NMPWAIT_WAIT_FOREVER)) { cout<<"当前没有可利用的命名管道实例!"<<endl; system("pause"); return; } /*打开管道连接*****************************************************/ hPipe=CreateFile("\\\\.\\pipe\\Communication",GENERIC_READ | GENERIC_WRITE, 0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(INVALID_HANDLE_VALUE==hPipe) { cout<<"打开命名管道失败!"<<endl; hPipe=NULL; system("pause"); return; } /*读写管道数据*****************************************************/ //写入数据 if(!WriteFile(hPipe,sebuf,strlen(sebuf)+1,&dwWrite,NULL)) { cout<<"写入数据失败!"<<endl; system("pause"); return; } //读取数据 if(!ReadFile(hPipe,rebuf,100,&dwRead,NULL)) { cout<<"读取数据失败!"<<endl; system("pause"); return; } cout<<rebuf<<endl; system("pause"); }
通信流程
#include<windows.h> #include<cstdlib> #include<iostream> #include<string> using namespace std; void main() { HANDLE hClip; char *pBuf; string str="this is message"; /*向剪贴板写入数据************************************************************************/ //打开剪贴板 if(OpenClipboard(NULL)) { //清空剪贴板 EmptyClipboard(); //想剪贴板写入数据 hClip=GlobalAlloc(GMEM_MOVEABLE,str.size()+1); pBuf=(char*)GlobalLock(hClip); strcpy(pBuf,str.c_str()); GlobalUnlock(hClip); SetClipboardData(CF_TEXT,hClip); //释放剪贴板 CloseClipboard(); } /*从剪贴板读取数据************************************************************************/ //打开剪贴板 if(OpenClipboard(NULL)) { //检查剪贴板中的数据格式 if(IsClipboardFormatAvailable(CF_TEXT)) { //接收数据 hClip=GetClipboardData(CF_TEXT); pBuf=(char*)GlobalLock(hClip); GlobalUnlock(hClip); cout<<pBuf<<endl; //释放剪贴板 CloseClipboard(); } } system("pause"); }
运行结果:
邮槽 匿名管道 命名管道 剪贴板 进程通讯 转自http://www.cnblogs.com/kzloser/archive/2012/11/04/2753367.html#
标签:
原文地址:http://www.cnblogs.com/candl/p/5740824.html