zoukankan      html  css  js  c++  java
  • c++下使用命名管道实现进程间通信

      前面已经使用邮槽实现过进程间通信:http://www.cnblogs.com/jzincnblogs/p/5192654.html ,这里使用命名管道实现进程间通信。

      与邮槽不同的是,命名管道在进程间传输数据是基于连接且可靠的传输方式,所以命名管道传输数据只能一对一。使用命名管道的步骤如下:

      ①创建命名管道,命名管道通过调用函数CreateNamedPipe()创建,函数原型如下:

     1 HANDLE WINAPI CreateNamedPipe(
     2   _In_     LPCTSTR               lpName,
     3   _In_     DWORD                 dwOpenMode,
     4   _In_     DWORD                 dwPipeMode,
     5   _In_     DWORD                 nMaxInstances,
     6   _In_     DWORD                 nOutBufferSize,
     7   _In_     DWORD                 nInBufferSize,
     8   _In_     DWORD                 nDefaultTimeOut,
     9   _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes
    10 );

      各参数的设置方法可参考MSDN:https://msdn.microsoft.com/zh-cn/biztalk/aa365150(v=vs.80)

      ②连接命名管道。当用户成功创建命名管道后便可调用相关函数连接命名管道,对于服务器而言,可以调用函数ConnectNamedPipe()等待客户端的连接请求,函数原型如下:

    1 BOOL WINAPI ConnectNamedPipe(
    2   _In_        HANDLE       hNamedPipe,
    3   _Inout_opt_ LPOVERLAPPED lpOverlapped
    4 );

      参数的设置方法:https://msdn.microsoft.com/zh-cn/biztalk/aa365150(v=vs.80)

      对于客户端而言,在连接服务器创建的命名管道前需要判断该命名管道是否可用,可调用函数WaitNamedPipe()实现,函数使用方法可参考MSDN:https://msdn.microsoft.com/zh-cn/subscriptions/aa365800

      当WaitNamedPipe()调用成功后,便可使用CreateFile()将命名管道打开已获得管道的句柄。

      ③读写命名管道,对命名管道的读写操作利用函数ReadFile()和WriteFile()完成,与上一篇的邮槽类似。

      服务器和客户端的实现代码如下:

      服务器端:

     1 //server
     2 //命名管道采用基于连接的可靠传输方式,只能一对一传输
     3 #include <windows.h>
     4 #include <iostream>
     5 
     6 #define BUF_SIZE 1024
     7 
     8 using std::cerr;
     9 using std::cout;
    10 using std::endl;
    11 
    12 int main()
    13 {
    14     HANDLE h_pipe;
    15     char buf_msg[BUF_SIZE];
    16     DWORD num_rcv; //实际接收到的字节数
    17     //创建命名管道,命名为MyPipe,消息只能从客户端流向服务器,读写数据采用阻塞模式,字节流形式,超时值置为0表示采用默认的50毫秒
    18     h_pipe = ::CreateNamedPipe("\\.\pipe\MyPipe", PIPE_ACCESS_INBOUND, PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUF_SIZE, BUF_SIZE, 0, nullptr);
    19     if (h_pipe == INVALID_HANDLE_VALUE)
    20     {
    21         cerr << "Failed to create named pipe!Error code: " << ::GetLastError() << "
    ";
    22         system("pause");
    23         return 1;
    24     }
    25     else
    26     {
    27         cout << "Named pipe created successfully...
    ";
    28     }
    29     //等待命名管道客户端连接
    30     if (::ConnectNamedPipe(h_pipe, nullptr))
    31     {
    32         cout << "A client connected...
    ";
    33         memset(buf_msg, 0, BUF_SIZE);
    34         //读取数据
    35         if (::ReadFile(h_pipe, buf_msg, BUF_SIZE, &num_rcv, nullptr))
    36         {
    37             cout << "Message received: " << buf_msg << "
    ";
    38         }
    39         else
    40         {
    41             cerr << "Failed to receive message!Error code: " << ::GetLastError() << "
    ";
    42             ::CloseHandle(h_pipe);
    43             ::system("pause");
    44             return 1;
    45         }
    46     }
    47     ::CloseHandle(h_pipe);
    48     ::system("pause");
    49     return 0;
    50 }

      客户端:

     1 //client
     2 #include <windows.h>
     3 #include <iostream>
     4 
     5 #define BUF_SIZE 1024
     6 
     7 using std::cerr;
     8 using std::cout;
     9 using std::endl;
    10 
    11 int main()
    12 {
    13     HANDLE h_pipe;
    14     char buf_msg[] = "Test for named pipe...";
    15     DWORD num_rcv; //实际接收到的字节数
    16     cout << "Try to connect named pipe...
    ";
    17     //连接命名管道
    18     if (::WaitNamedPipe("\\.\pipe\MyPipe", NMPWAIT_WAIT_FOREVER))
    19     {
    20         //打开指定命名管道
    21         h_pipe = ::CreateFile("\\.\pipe\MyPipe", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
    22         if (h_pipe == INVALID_HANDLE_VALUE)
    23         {
    24             cerr << "Failed to open the appointed named pipe!Error code: " << ::GetLastError() << "
    ";
    25             ::system("pause");
    26             return 1;
    27         }
    28         else
    29         {
    30             if (::WriteFile(h_pipe, buf_msg, BUF_SIZE, &num_rcv, nullptr))
    31             {
    32                 cout << "Message sent successfully...
    ";
    33             }
    34             else
    35             {
    36                 cerr << "Failed to send message!Error code: " << ::GetLastError() << "
    ";
    37                 ::CloseHandle(h_pipe);
    38                 ::system("pause");
    39                 return 1;
    40             }
    41         }
    42         ::CloseHandle(h_pipe);
    43     }
    44     ::system("pause");
    45     return 0;
    46 }
  • 相关阅读:
    《Python编程:从入门到实践》第四章 操作列表 习题答案
    Linux学习笔记(十六)Linux网络管理:网络基础(一)
    《Python编程:从入门到实践》第三章 列表简介 习题答案
    《Python编程:从入门到实践》第二章 变量和简单数据类型 习题答案
    想要上网满速?安装200兆以上宽带后请做到这几点
    从编程小白到入门码农的五个途径
    一行终端命令干掉一个小型网站
    用Python讲述冯绍峰和赵丽颖的爱情故事
    Python: 如何判断远程服务器上Excel文件是否被人打开
    Python: Django简介
  • 原文地址:https://www.cnblogs.com/jzincnblogs/p/5192763.html
Copyright © 2011-2022 走看看