进程间通信 - 管道

管道(Pipe)是一种用于进程间共享数据的机制,实质是共享一段内存,windows系统为这段共享内存设计采用数据流I/O的方式访问。由一个读一个写,类似于一个管道两端。

管道分为命名管道和匿名管道。

匿名管道只能在父子进程间进行通信,不能在网络间通信,而数据传输是单向的。

命名管道可以在任意进程间通信,通信是双向的。

创建命名管道 CreateNamedPipe

HANDLE WINAPI CreateNamedPipe(

  LPCTSTR lpName,              // 管道名称, 命名方式:\\ServerName\pipe\PipeName 或者 \\.\pipe\PipName

  DWORD dwOpenMode,      // 打开模式

    DWORD dwPipMode,         // 管道模式(管道类型模式、管道读写模式、管道等待模式)

  DWORD nMaxInstances,   //pipe所能建立的最多实例

  DWORD nOutBufferSize,   //输入缓存大小

  DWORD nInBufferSize,     //输出缓存大小

  DWORD nDefaultTimeOut, 

  LPSECURITY_ATTRIBUTES lpSecurity_attributes

);

服务端等待客户端连接的函数ConnectNamedPipe

BOOL WINAPI ConnectNamedPipd(

  HANDLE hNamedPipe,

  LPOVERLAPPED lpOverlapped  //指向OVERLAPPED结构的指针

);

管道关闭DisconnectNamedPipe

等待状态改变WaitNamedPipe

客户端使用CreateFile打开管道

pipe读写使用 ReadFile 和 WriteFile

例子:(服务端C++ 客户端Delphi)

服务端(部分代码):

/* 创建命名管道   */                                                           

void severpipe::CreateAndConnectInstance()

{

   m_hpipe=CreateNamedPipe(m_lpszpipename,   

                  PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,  

                  PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE ,  

                                               PIPE_UNLIMITED_INSTANCES,   

                                               BUFSIZ*sizeof(TCHAR),  

                                              BUFSIZ*sizeof(TCHAR),   1000,   NULL   );

   

  if (INVALID_HANDLE_VALUE==m_hpipe)

   {

    std::cerr<<GetLastError()<<std::endl;

   }

}

/* 建立连接    */                                                         

void severpipe::ConnectToNewClient()

{

  BOOL fConnected = FALSE;

  fConnected=ConnectNamedPipe(m_hpipe, &oConnect);

   if (!fConnected)

   {

    if (ERROR_IO_PENDING!=GetLastError())

    {

      std::cout<<"connect failed"<<std::endl;

    }

  }

}

/*  读取函数 返回读取内容   */

char* severpipe::PipeReadStr()

{

  char* preadbuf = new char[5];

   DWORD dwRead;
  memset(preadbuf, 0, 5);
  if (!ReadFile(m_hpipe, preadbuf, 5, &dwRead, NULL))

   {

    std::cout<<"read failed"<<std::endl;

  }
  return preadbuf;

}

客户端(部分代码):

if(WaitNamedPipe(pipename, NMPWAIT_WAIT_FOREVER)=False) then  

begin    

  mmo.Lines.Add('pipe do not exist');    

  Exit;  

end;

//const pipename = '\\.\pipe\samplenamedpipe';  

hpipe := createfile(PChar(pipename), GENERIC_READ or GENERIC_WRITE,  0,  nil,  OPEN_EXISTING,  0, 0); 

if hpipe=INVALID_HANDLE_VALUE then  

begin    

  mmo.Lines.Add('can not open pipe');    

  Exit;  

end;

if( WriteFile(hpipe, PChar(str)^, Length(str),written,nil)=False) then  //  str:= 'test';

begin    

  mmo.Lines.Add('wirte failed');  

  Exit;  

end;

PS:仅供参考, 需要考虑同步问题,可以使用WaitForSingleObject

转载于:https://www.cnblogs.com/zxcode/archive/2011/03/10/1977619.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值