进程间通讯

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

 进程间通讯  一、说明进程间通讯的必要性及困难性  

二、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;  

 hMapFile= CreateFileMapping(NULL,NULL,PAGE_READWRITE,0,10,"YuanMap");

  if (hMapFile == 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);   --------------------------------------------(完)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值