mark:命名管道学习笔记

一、简介

命名管道(NamedPipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是:命名管道可以在不相关的进程之间和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。

二、接口函数介绍

服务端使用函数
创建命名管道
CreateNamedPipe创建命名管道
ConnectNamedPipe服务器端等待客户端连接命名管道。若调用此函数之前,客户端已经调用CreateFile连接到了此实例,ConnectNamedPipe返回FALSE,并且GetLastError()返回ERROR_PIPE_CONNECTED,这是一个正常的连接,虽然函数返回了FALSE
WriteFile/ReadFile
DisconnectNamedPipe断开一个客户与一个命名管道的连接,服务器端强制关闭命名管道的客户端;客户进程仍然需要调用CloseHandle。服务器端可以进一步再与其他客户端连接
CloseHandle关闭命名管道

客户端使用函数
连接到命名管道某个实例
WaitNamedPipe如果指定的命名管道没有实例存在,即没有服务端创建该命名管道,函数无视超时等待时间直接返回0。如果函数执行成功返回TRUE,表示至少有一个命名管道的实例有效
CreateFile使用CreateFile函数打开命名管道的一个句柄,CreateFile可能会打开管道失败,因为该实例有可能被服务端关闭或被已经被其他客户端打开
WriteFile/ReadFile
CloseHandle

ConnectNamedPipe参数简介:

备注:实际应用中,我们用管道传输音视频帧数据,需要配置PipeMode为PIPE_TYPE_MESSAGE、PIPE_READMODE_MESSAGE。

三、示例 

客户端代码示例:

#include <windows.h>  
#include <stdio.h>  
#include <tchar.h>
#include <string>

/*client demo code*/
int main( ) {

    HANDLE PipeHandle;
    DWORD BytesWritten;
    const char* message = "hello world";

    std::string name = "\\\\.\\pipe\\test";

    TCHAR pipename[MAX_PATH] = { 0 };

#ifdef UNICODE 
    _stprintf_s(pipename, MAX_PATH, _T("%S"), name.c_str());//%S宽字符
#else 
    _stprintf_s(pipename, MAX_PATH, _T("%s"), name.c_str());//%s单字符
#endif

    if (WaitNamedPipe(pipename, NMPWAIT_WAIT_FOREVER) == 0)
    {
        printf("WaitNamedPipe failed with error %d\n",
            GetLastError());
        return -1;
    }

    // Open the named pipe file handle  
    if ((PipeHandle = CreateFile(pipename,
        GENERIC_READ | GENERIC_WRITE, 0,
        (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        (HANDLE)NULL)) == INVALID_HANDLE_VALUE)
    {
        printf("CreateFile failed with error %d\n", GetLastError());
        return -1;
    }

    if (WriteFile(PipeHandle, message, strlen(message), &BytesWritten, NULL) == 0)
    {
        printf("WriteFile failed with error %d\n", GetLastError());
        CloseHandle(PipeHandle);
        return -1;
    }

    printf("Wrote %d bytes", BytesWritten);

    CloseHandle(PipeHandle);

    return 0;
}

 服务端代码示例:

#include <windows.h>  
#include <stdio.h>  
#include <tchar.h>
#include <string> 

/*server demo code*/
int main(void)
{
    HANDLE PipeHandle;
    DWORD BytesRead;
    CHAR buffer[256];

    std::string name = "\\\\.\\pipe\\test";

    TCHAR pipename[MAX_PATH] = { 0 };

#ifdef UNICODE 
    _stprintf_s(pipename, MAX_PATH, _T("%S"), name.c_str());//%S宽字符
#else 
    _stprintf_s(pipename, MAX_PATH, _T("%s"), name.c_str());//%s单字符
#endif

    if ((PipeHandle = CreateNamedPipe(pipename,
        PIPE_ACCESS_DUPLEX, //open mode  
        PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, //  pipe mode 
        1,//Num. of MaxInstances: between 1 and PIPE_UNLIMITED_INSTANCES  
        0, // out buffer size  
        0, // in buffer size  
        1000, //timeout  
        NULL //Security descriptor  
    )) == INVALID_HANDLE_VALUE)
    {
        printf("CreateNamedPipe failed with error %d\n",
            GetLastError());
        return 0;
    }

    printf("Server is now running\n");

    if (ConnectNamedPipe(PipeHandle, NULL) == 0)
    {
        printf("ConnectNamedPipe failed with error %d\n", GetLastError());
        CloseHandle(PipeHandle);
        return 0;
    }

    if (ReadFile(PipeHandle, buffer, sizeof(buffer), &BytesRead, NULL) <= 0)
    {
        printf("ReadFile failed with error %d\n", GetLastError());
        CloseHandle(PipeHandle);
        return 0;
    }

    printf("%.*s\n", BytesRead, buffer);

    if (DisconnectNamedPipe(PipeHandle) == 0)
    {
        printf("DisconnectNamedPipe failed with error %d\n",
            GetLastError());
        return 0;
    }

    CloseHandle(PipeHandle);
    return 0;
}


注意示例中先执行服务端,后执行客户端。

四、管道状态查询两种办法 

1)PowerShell

命令行:[System.IO.Directory]::GetFiles("\\.\\pipe\\")

2)Google Chrome浏览器

命令行:file://.//pipe//

五、参考

1、命名管道服务端使用说明 https://docs.microsoft.com/en-us/windows/win32/ipc/multithreaded-pipe-serverhttps://docs.microsoft.com/en-us/windows/win32/ipc/multithreaded-pipe-server

2、命名管道客户端使用说明

https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipe-clienthttps://docs.microsoft.com/en-us/windows/win32/ipc/named-pipe-client

3、函数列表

https://docs.microsoft.com/en-us/windows/win32/ipc/pipe-functionshttps://docs.microsoft.com/en-us/windows/win32/ipc/pipe-functions

4、创建命名管道参数详解

进程通信之二 管道技术第三篇 命名管道_MoreWindows Blog-CSDN博客上一篇《进程通信之二管道技术第二篇匿名管道》中讲解了匿名管道,匿名管道有读取端和写入端,在创建匿名管道(CreatePipe)后就可以像读写文件一样的对管道中进行读写(ReadFile与WriteFile,注意读写顺序)。在关闭匿名管道两端后会由系统负责销毁并回收资源。文章中还示范了父进程如何使用匿名管道来改变子进程的输入输出。 本篇将讲解管道技术中的命名管道(Named Pipes),顾名思义,https://blog.csdn.net/MoreWindows/article/details/8260087?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

5、关于模式PIPE_TYPE_MESSAGE模式

关于命名管道应用 及其中的使用方式:消息模式(PIPE_TYPE_MESSAGE)_firfor_新浪博客关于命名管道应用 及其中的使用方式:消息模式(PIPE_TYPE_MESSAGE)_firfor_新浪博客,firfor,http://blog.sina.com.cn/s/blog_71b3a9690100usem.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值