
进程间通讯一种机制,操作系统进程和线程通过它交来自换数据和消息。IPC 包括本地机制(如 Windows 共享内存)或者网络机制(如 Windows 套接字)。
- 中文名称 进程间通讯
- 所属学科 计算机科学与技术
基本简介
进程间通讯的方式
Socket,剪切板方法,内存映射文件, 邮槽方法, 命名管道, 匿名管道方法
实现方法
来自一、Socket的方法
对于不同机器上且数据量很多的情况会有很大的帮助,但对于同一台机器之间的不同进程之间的通讯就不方便了 (代码量太多)
进程间通讯的剪切屋板方法
a、对于发送端:
360百科 CString str;
采立室风杨微 GetDlgItemText(IDC_EDIT1,str);
HANDLE hGlobal;
if(this->OpenClipboard())//获取剪切板的资源所有权
{
EmptyClipboard();//将剪切板的内容清空
hGlobal=Gl者立obalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//在堆上分配一块用于存放数据的空间,程序返回一个内存句柄
char* pBuf=(下条计char*)GlobalLock(hGlobal);//将内存块句柄转化成一住丰格耐顾村型早坚个指针,并将相应的引用根害夜报计数器加一
strcpy(pBuf,str.GetB裂衡门uffer(str.GetLength()));//将字符串拷入指定的内存块中
GlobalUnlock(hGlobal);//将引用计数器数字减一
::S哪etClipboardData(CF_TEXT,hGlobal);//将存放有数据的内存块放入剪切板的资源管理中
::CloseClipboard(务罗食茶提补历);//释放剪切板的资源占用权
}
b、对于客户端
if(this->OpenClipboard()顺存罪际阻跑击顶灯厚顺)//获取剪切板的资源所有权
{
HANDLE hGlobal=::GetClipboardData(CF_TEXT);从剪切板中取出一个内存的句柄
char* pBuf=(char*)GlobalLock(hGlobal);//将内存句柄值转化为一个指针,并将内存块的引用计数器加已磁常没顾二一
SetDlgItemText(IDC_EDIT2,pBuf);
GlobalUnlock(hGlobal);//将内存块的引用计数器减一
Clos卫磁尔格帮eClipboard()措点八段着不免旧又;//释放剪切板资源的占用权
}
内存映射文件方法
1、 服务器端代码:
HANDLE hMapFi信限者天案精宣点势le;
hMapFile= CreateFileMapping(NULL,NULL,PAGE_R笔杀命当EADWRITE,0,10,"YuanMap");
if (hM觉理权则临来风道绍apFile == NULL)
免色火应确服台东 {
AfxMessageBox("CreateFileMapping出错!");
return;
}
LPVOID pFile;
pFile= MapViewOfFile(hMapFile,FILE_MAP_WRITE|FILE_MAP_READ,0,0,0);
if (pFile == NULL)
{
句果以器散 AfxMessageBox("MapViewOfFile出错!");
return;
}
CString str;
GetDlgItemText(IDC_EDIT1,str);
strcpy((char*)pFile,str.GetBuffer(str.GetLength()));
//CloseHandle(hMapFile); //不能加,否则客户端收不到,所以一般会将这个句柄作为一个全局变量
2、 客户机端代码:
HANDLE hMap;
hMap= OpenFileMapping(FILE_MAP_READ|FILE_MAP_WRITE,
TRUE,
"YuanMap");
LPVOID pVoid;
pVoid=::MapViewOfFile(hMap,FILE_MAP_READ,0,0,0);
CString str=(char*)pVoid;
SetDlgItemText(IDC_EDIT1,str);
UnmapViewOfFile(pVoid);
CloseHandle(hMap);
进程间通讯的邮槽方法
1、 邮槽采用的是一种广播机制。
2、 邮槽采用的是一种直接基于文件系统开发而成,所以它不依赖于某种具体的网络协议。
3、 邮槽每次传送的消息长度不能长于422字节。
4、 发送端代码如下:(客户端)
HANDLE hslot;
hslot=CreateFile("\\\\\\\\.\\\\mailslot\\\\myslot",GENERIC_WRITE,
FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,
NULL);
if(!hslot)
{
MessageBox("打开邮槽失败!");
return;
}
char *pBuf="专业的编程语言培训";
DWORD dwWrite;
WriteFile(hslot,pBuf,strlen(pBuf)+1,&dwWrite,NULL);
CloseHandle(hslot);
5、 接收端代码如下:(服务器端)
HANDLE hMail;
hMail=CreateMailslot("\\\\\\\\.\\\\mailslot\\\\myslot",0,
MAILSLOT_WAIT_FOREVER,NULL);
if(INVALID_HANDLE_VALUE==hMail)
{
MessageBox("创建邮槽失败!");
return;
}
HANDLE hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
OVERLAPPED ovlap;
ZeroMemory(&ovlap,sizeof(ovlap));
ovlap.hEvent=hEvent;
char buf[200];
DWORD dwRead;
if(FALSE==ReadFile(hMail,buf,200,&dwRead,&ovlap))
{
if(ERROR_IO_PENDING!=GetLastError())
{
MessageBox("读取操作失败!");
CloseHandle(hMail);
return;
}
}
WaitForSingleObject(hEvent,INFINITE);
MessageBox(buf);
ResetEvent(hEvent);
CloseHandle(hMail);
进程间通讯的命令管道方法
A、对于发送端代码如下:
HANDLE handle;
handle=CreateNamedPipe("\\\\\\\\.\\\\pipe\\\\MyPipe",
PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
1,0,0,1000,NULL);//创建一个命名管道连结
ConnectNamedPipe(handle,NULL);//在命名管道实例上监听客户机连结请求
char buf[200]="http://www.it315.org";
DWORD dwWrite;
WriteFile(handle,buf,strlen(buf)+1,&dwWrite,NULL);//往管道里写数据
CloseHandle(handle);//关闭管道
B、对于接收端代码如下:
HANDLE hNamedPipe;
WaitNamedPipe("\\\\\\\\.\\\\pipe\\\\MyPipe",NMPWAIT_WAIT_FOREVER);//等候一个命名管道实例可供自己使用
hNamedPipe=CreateFile("\\\\\\\\.\\\\pipe\\\\MyPipe",GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//建立与命名管道的连结
char buf[200];
DWORD dwRead;
ReadFile(hNamedPipe,buf,200,&dwRead,NULL);//从命名管道中读取数据
MessageBox(buf);
CloseHandle(hNamedPipe);//关闭与命名管道服务器的连结
进程间通讯的匿名管道方法
父进程:
A、对于父进程中创建一个管道代码如下:
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
if(FALSE==CreatePipe(&hRead,&hWrite,&sa,0))//创建一个匿名的管道,得到一个用于从管道读取的句柄,一个用于向管道写数据用的句柄
{
MessageBox("Create pipe failed!");
return;
}
STARTUPINFO sui;
ZeroMemory(&sui,sizeof(sui));
sui.cb=sizeof(sui);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);
PROCESS_INFORMATION pi;
CreateProcess("..\\\\PipeCli\\\\Debug\\\\PipeCli.exe",NULL,
NULL,NULL,TRUE,CREATE_DEFAULT_ERROR_MODE,/*0*/
NULL,NULL,&sui,&pi);//创建一个新的子进程,并将准备好的句柄信息传给子进程
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
B、父进程中从管道读取代码如下:
char buf[200];
DWORD dwRead;
ReadFile(hRead,buf,200,&dwRead,NULL);
MessageBox(buf);
C、父进程中往管道写入代码如下:
char buf[200]="专业的编程语言培训";
DWORD dwWrite;
WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL);
子进程:
首先得到用于管道读取与写入用的句柄值(最好是放在视图的初始化更新函数里)
hRead=GetStdHandle(STD_INPUT_HANDLE);
hWrite=GetStdHandle(STD_OUTPUT_HANDLE);
读取部分代码:
char buf[200];
DWORD dwRead;
ReadFile(hRead,buf,200,&dwRead,NULL);
MessageBox(buf);
写入部分代码:
char buf[200]="http://www.it315.org";
DWORD dwWrite;
WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL);
--------------------------------------------(完)