团灭Windows进程通信(六)——最常用到命名管道

文章来源:http://blog.csdn.net/huanglong8/article/details/53900647

上一章我们提到了匿名管道,匿名管道在处理重定向时,是比较好用的。但局限于管道数量和输入输出的限制,有时并不能满足通信开发工作。这时就要用到命名管道。

关于命名管道,网上已有大多数例子和说明

参考:
进程间通信 - 命名管道实现

命名管道的特点在于

  1. 它有名字,好使用,可断可连,像socket。
  2. 同级进程通信,跨网络进程间通信,双向传输
  3. 代码短,理解简单。
  4. 阻塞接收消息传递

创建命名管道

HANDLE  WINAPI   CreateNamedPipe(
   __in    LPCTSTR lpName,
  __in    DWORD dwOpenMode,
  __in    DWORD dwPipeMode,
  __in    DWORD nMaxInstances,
   __in    DWORD nOutBufferSize,
  __in    DWORD nInBufferSize,
   __in    DWORD nDefaultTimeOut,
  __in    LPSECURITY_ATTRIBUTES lpSecurityAttributes
               );

参数 lpName,其格式必须为 “\.\pipe\name” ,其中圆点 ”.” 表示的是本地机器。

连接管道

BOOL  WINAPI  ConnectNamedPipe(
          __in    HANDLE hNamedPipe,
          __in    LPOVERLAPPED lpOverlapped
          );

参数 lpOverlapped 指向一个 OVERLAPPED 结构的指针,

如果 hNamedPipe 所标识的命名管道是用 FILE_FLAG_OVERLAPPED ,

(也就是重叠模式或者说异步方式)标记打开的,则这个参数不能为 NULL ,

必须是一个有效的指向一个 OVERLAPPED 结构的指针,否则该函数可能会错误的执行。

等待有管道连接的请求

BOOL  WINAPI  WaitNamedPipe(
        __in    LPCTSTR lpNamedPipeName,
         __in    DWORD nTimeOut
          );

闲话不说了,我也懒的粘了,直接说示例。

示例中,仍然以两个线程作为IO读写,并且使用两个管道来进行数据收发,虽然命名管道是可以双向的。

程序A中示例代码:

定义管道和线程

HANDLE hSendThread,hRecvThread;
LPDWORD hSendThreadID,hRecvThreadID;

#define NAMEDPIPEA "\\\\.\\pipe\\pipea" 
#define NAMEDPIPEB "\\\\.\\pipe\\pipeb"

发送线程

DWORD WINAPI Send(LPVOID lpParameter )
{
    while(1)
    {
        if(WaitNamedPipe(NAMEDPIPEA,NMPWAIT_WAIT_FOREVER))
        {
            printf("Connect pipe instance.\n");
            break;
        }
        Sleep(1000);
    }
    HANDLE hPipe = CreateFile(NAMEDPIPEA,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(INVALID_HANDLE_VALUE == hPipe)
    {
        printf("Open the pipe error.%d\n",GetLastError());
        CloseHandle(hPipe);
        hPipe = 0;
        return 0;
    }
    DWORD dwd;
    char buff[0xFFF] = {0};
    while(true)
    {
        gets_s(buff,sizeof(buff));
        WriteFile(hPipe,buff,0xFFF,&dwd,0);
    }
    return 0;
}

接收线程

DWORD WINAPI Recv(LPVOID lpParameter )
{
    HANDLE hPipe = CreateNamedPipe(NAMEDPIPEB,PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,0,1,1024,1024,0,0);
    if(INVALID_HANDLE_VALUE == hPipe)
    {
        printf("Create Named Pipe Error.%d\n",GetLastError());
        return 0;
    }
    if(!ConnectNamedPipe(hPipe,0))
    {
        printf("Wait for client connection error.%d\n",GetLastError());
        CloseHandle(hPipe);
        hPipe = 0;
        return 0;
    }
    char buff[0xFFF];
    ZeroMemory(buff,sizeof(buff));
    DWORD bytesRead;
    while(true)
    {
        if(ReadFile(hPipe,buff,0xFFF,&bytesRead,NULL)!=NULL)
        {
            printf("receive from B: %s\n",buff);
        }
    }
}

主调函数

int main(int argc, char *argv[])
{
    hSendThread = CreateThread(NULL,0,Send,NULL,NULL,hSendThreadID);
    hRecvThread = CreateThread(NULL,0,Recv,NULL,NULL,hRecvThreadID);
    if( WaitForSingleObject(hSendThread,INFINITE))
        CloseHandle(hSendThread);
    if( WaitForSingleObject(hRecvThread,INFINITE))
        CloseHandle(hRecvThread);

    return 0;
}

程序B中是大同小异,就是将两个线程的管道名反过来就可以了。

示例源代码已分享至:

Windows进程通信_NamedPipe 下载

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值