进程间通讯

更新时间:2024-08-17 21:09

进程间通讯一种机制,操作系统进程线程通过它交换数据和消息。IPC 包括本地机制(如 Windows 共享内存)或网络机制(如 Windows 套接字)。

基本介绍

进程间通讯的方式

Socket,剪切板方法,内存映射文件, 邮槽方法, 命名管道, 匿名管道方法

实现方法

一、Socket的方法

对于不同机器上且数据量很多的情况会有很大的帮助,但对于同一台机器之间的不同进程之间的通讯就不方便了 (代码量太多)

进程间通讯的剪切板方法

a、对于发送端:

CString str;

GetDlgItemText(IDC_EDIT1,str);

HANDLE hGlobal;

if(this->OpenClipboard())//获取剪切板的资源所有权

{

EmptyClipboard();//将剪切板的内容清空

hGlobal=GlobalAlloc(GMEM_MOVEABLE,str.GetLength()+1);//在堆上分配一块用于存放数据的空间,程序返回一个内存句柄

char* pBuf=(char*)GlobalLock(hGlobal);//将内存块句柄转化成一个指针,并将相应的引用计数器加一

strcpy(pBuf,str.GetBuffer(str.GetLength()));//将字符串拷入指定的内存块中

GlobalUnlock(hGlobal);//将引用计数器数字减一

::SetClipboardData(CF_TEXT,hGlobal);//将存放有数据的内存块放入剪切板的资源管理中

::CloseClipboard();//释放剪切板的资源占用权

}

b、对于客户端

if(this->OpenClipboard())//获取剪切板的资源所有权

{

HANDLE hGlobal=::GetClipboardData(CF_TEXT);从剪切板中取出一个内存的句柄

char* pBuf=(char*)GlobalLock(hGlobal);//将内存句柄值转化为一个指针,并将内存块的引用计数器加一

SetDlgItemText(IDC_EDIT2,pBuf);

GlobalUnlock(hGlobal);//将内存块的引用计数器减一

CloseClipboard();//释放剪切板资源的占用权

}

内存映射文件方法

1、 服务器端代码:

HANDLE hMapFile;

if (hMapFile == NULL)

{

return;

}

LPVOID pFile;

pFile= MapViewOfFile(hMapFile,FILE_MAP_WRITE|FILE_MAP_READ,0,0,0);

if (pFile == NULL)

{

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,

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;

FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,

NULL);

if(!hslot)

{

return;

}

DWORD dwWrite;

WriteFile(hslot,pBuf,strlen(pBuf)+1,&dwWrite,NULL);

CloseHandle(hslot);

5、 接收端代码如下:(服务器端)

HANDLE hMail;

MAILSLOT_WAIT_FOREVER,NULL);

if(INVALID_HANDLE_VALUE==hMail)

{

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())

{

CloseHandle(hMail);

return;

}

}

WaitForSingleObject(hEvent,INFINITE);

MessageBox(buf);

ResetEvent(hEvent);

CloseHandle(hMail);

进程间通讯的命令管道方法

A、对于发送端代码如下:

HANDLE handle;

PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,

1,0,0,1000,NULL);//创建一个命名管道连结

ConnectNamedPipe(handle,NULL);//在命名管道实例上监听客户机连结请求

DWORD dwWrite;

WriteFile(handle,buf,strlen(buf)+1,&dwWrite,NULL);//往管道里写数据

CloseHandle(handle);//关闭管道

B、对于接收端代码如下:

HANDLE hNamedPipe;

命名管道实例可供自己使用

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))//创建一个匿名的管道,得到一个用于从管道读取的句柄,一个用于向管道写数据用的句柄

{

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;

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、父进程中往管道写入代码如下:

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);

写入部分代码:

DWORD dwWrite;

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

--------------------------------------------(完)

免责声明
隐私政策
用户协议
目录 22
0{{catalogNumber[index]}}. {{item.title}}
{{item.title}}