正文

附录:进程间通讯2007-09-26 19:06:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lym51/29688.html

分享到:

附录:进程间通讯

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

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

--------------------------------------------(

阅读(4709) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册