您的位置:首页 > 其它

【IPC进程间通讯之二】管道Pipe

2014-05-15 15:38 369 查看


IPC进程间通信+管道Pipe

      

        IPC(Inter-Process Communication,进程间通信)。

        管道用于进程间共享数据,其实质是共享内存,常用IPC之一。管道不仅可以用于本机进程间通信,还可实现跨网络进程间通信,如同Socket通信,管道同样封装计算机底层网络实现,提供一个良好的API接口。

       
       1.管道(Pipe):

       管道分为匿名管道和命名管道。
       匿名管道只能用于父子进程间通信 ,不能跨网络通信,并且通信是单向。
       命名管道可用于任意进程间通信,支持跨网络通信,并且通信是双向,任意一段都可以接收和发送数据。命名管道是学习的重点。
       命名管道通信进程分为服务端和客户端,服务端创建Pipe,客户端通过管道名连接该Pipe之后,双方均可通过该Pipe发送和接收数据。
       

        2.邮槽命名 :

       本机上格式:\\ServerName\Pipe\name

       如:\\.\Pipe\my_pipe

       [b]3.基本API函数 :[/b]
创建命名管道:
        HANDLE    CreateNamedPipe(

                        LPCTSTR   lpName,                // 指向管道名称的指针

                        DWORD     dwOpenMode,       // 管道打开模式

                        DWORD     dwPipeMode,
      // 管道模式

                        DWORD     nMaxInstances,     // 最大实例数

                        DWORD     nOutBufferSize,   // 输出缓存大小

                        DWORD     nInBufferSize,       // 输入缓存大小

                        DWORD    nDefaultTimeOut, // 超时设置
LPSECURITY_ATTRIBUTES lpSecurityAttributes   // 安全属性指针

);

        该函数用于服务器端创建命名管道。
等待客户端连接:
        BOOL  ConnectNamedPipe(
                     HANDLE    hNamedPipe,        //管道句柄
                     LPOVERLAPPED   lpOverlapped     //设为NULL
); 

        该函数用于服务器等待客户端连接到管道。
检查命名管道:
        BOOL  WaitNamedPipe(
                     LPCTSTR   lpNamedPipeName,  //管道名
                     DWORD     nTimeOut                  //超时
);

         该函数用于客户端检查是否存在管道Pipe。
打开命名管道:

        BOOL  CreateFile(

                     LPCTSTR   lpFileName,

                     DWORD     dwDesiredAccess,

                     DWORD     dwShareMode,

                     LPSECURITY_ATTRIBUTES   lpSecurityAttributes,

                     DWORD    dwCreationDisposition,

                     DWORD    dwFlagsAndAttributes,

                    HANDLE    hTemplateFile
 
);

         第一个参数:管道名指针。

         第二个参数:访问模式。

         第三个参数:共享模式。

         第四个参数:安全属性指针。

         第五个参数:创建选项。

         第六个参数:文件属性。

         第七个参数:用于复制文件句柄。

         该函数用于打开一个管道,并返回管道句柄。

读取管道:       
        BOOL ReadFile(

                    HANDLE    hFile,

                    LPVOID     lpBuffer,

                    DWORD    nNumberOfBytesToRead,

                    LPDOWRD    lpNumberOfBytesRead,

                    LPOVERLAPPED   lpOverlapped);


        第一个参数:管道句柄。
        第二个参数:缓存地址。
        第三个参数:消息的长度。
        第四个参数:实际读取的长度。
        第五个参数:一般设置为NULL。
        该函数用于读取管道内数据。

写入管道:

        BOOL  WriteFile(

                     HANDLE    hFile,

                     LPCVOID   lpBuffer,

                     DWORD     nNumberOfBytesToWrite,

                     LPDWORD   lpNumberOfBytesWritten,

                     LPOVERLAPPED    lpOverlapped);


         第一个参数:管道句柄。

         第二个参数:数据缓冲区指针。


         第三个参数:写入字节数。


         第四个参数:返回实际写入字节数。


         第五个参数:结构体指针,一般置NULL。


         该函数用于客户端向管道写入数据。

         4.牛刀小试 : 

         先在VC6.0中运行服务端程序,在运行客户端程序。



         运行效果:




服务器程序:

#include
#include

int main()
{
char Buffer[10000];
DWORD ReadNum;

//创建命名管道
HANDLE my_pipe=CreateNamedPipe(
"\\\\.\\Pipe\\Test",
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE|PIPE_READMODE_BYTE,
1,
0,
0,
1000,
NULL);
printf("Pipe server running...\n");

//等待连接
if(ConnectNamedPipe(my_pipe,NULL)==FALSE)
{
CloseHandle(my_pipe);
printf("建立连接失败!");
return 0;
}
else
{
while(1)
{
//接收数据
ReadFile(my_pipe,Buffer,sizeof(Buffer),&ReadNum,NULL);
Buffer[ReadNum]='\0';
printf("来自客户端的数据:  %s \n",Buffer);

//发送数据
char *Data="I am a pipe server !";
WriteFile(my_pipe,Data,strlen(Data),&ReadNum,NULL);

}
//关闭管道
DisconnectNamedPipe(my_pipe);
}
}

客户端程序:

#include
#include

int main()
{
char Data[256]="I am client !";
char Buffer[256];
DWORD WriteNum;
printf("pipe client is running!\n");

//检查管道是否存在
WaitNamedPipe("\\\\.\\Pipe\\Test",NMPWAIT_WAIT_FOREVER);

//打开管道
HANDLE hPipe=CreateFile("\\\\.\\Pipe\\Test",
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);

while(1)
{
//写入管道
WriteFile(hPipe,Data,strlen(Data),&WriteNum,NULL);
getchar();

//读取管道
ReadFile(hPipe,Buffer,sizeof(Buffer),&WriteNum,NULL);
Buffer[WriteNum]='\0';
printf("来自服务器的数据: %s",Buffer);
}

CloseHandle(hPipe);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息