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() << "\n";
22         system("pause");
23         return 1;
24     }
25     else
26     {
27         cout << "Named pipe created successfully...\n";
28     }
29     //等待命名管道客户端连接
30     if (::ConnectNamedPipe(h_pipe, nullptr))
31     {
32         cout << "A client connected...\n";
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 << "\n";
38         }
39         else
40         {
41             cerr << "Failed to receive message!Error code: " << ::GetLastError() << "\n";
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...\n";
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() << "\n";
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...\n";
33             }
34             else
35             {
36                 cerr << "Failed to send message!Error code: " << ::GetLastError() << "\n";
37                 ::CloseHandle(h_pipe);
38                 ::system("pause");
39                 return 1;
40             }
41         }
42         ::CloseHandle(h_pipe);
43     }
44     ::system("pause");
45     return 0;
46 }

 

转载于:https://www.cnblogs.com/jzincnblogs/p/5192763.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Windows 中,可以使用命名管道(Named Pipes)实现进程间通信。以下是一些基本步骤: 1. 创建命名管道 使用 CreateNamedPipe 函数创建一个命名管道。该函数需要指定管道名称、管道的读写模式、管道的最大实例数等参数。 2. 等待客户端连接 使用 ConnectNamedPipe 函数等待客户端的连接。该函数会一直阻塞,直到有客户端连接成功。 3. 接收客户端数据 使用 ReadFile 函数从管道中读取客户端发送的数据。 4. 发送数据给客户端 使用 WriteFile 函数向管道中写数据,以便客户端读取。 5. 断开连接 使用 DisconnectNamedPipe 函数断开与客户端的连接。如果需要与多个客户端通信,则返回第 2 步。 6. 关闭管道 使用 CloseHandle 函数关闭命名管道的句柄。 注意事项: - 在创建管道时,需要指定管道名称,该名称在系统中必须是唯一的。 - 管道支持同步和异步方式进行读写操作,可以根据具体需求选择使用哪种方式。 - 管道的读写操作是阻塞式的,也可以使用 overlapped 结构体实现异步操作。 下面是一个简单的代码示例,演示如何使用命名管道实现进程间通信: ``` #include <windows.h> #include <stdio.h> #define PIPE_NAME "\\\\.\\pipe\\MyPipe" int main() { HANDLE hPipe; char buffer[1024]; DWORD dwRead; // 创建命名管道 hPipe = CreateNamedPipe(PIPE_NAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, NULL); if (hPipe == INVALID_HANDLE_VALUE) { printf("CreateNamedPipe failed! Error code: %d\n", GetLastError()); return 1; } // 等待客户端连接 if (!ConnectNamedPipe(hPipe, NULL)) { printf("ConnectNamedPipe failed! Error code: %d\n", GetLastError()); return 1; } // 接收客户端数据 if (!ReadFile(hPipe, buffer, sizeof(buffer), &dwRead, NULL)) { printf("ReadFile failed! Error code: %d\n", GetLastError()); return 1; } printf("Received data from client: %s\n", buffer); // 发送数据给客户端 if (!WriteFile(hPipe, "Hello, client!", 15, NULL, NULL)) { printf("WriteFile failed! Error code: %d\n", GetLastError()); return 1; } // 断开连接 DisconnectNamedPipe(hPipe); // 关闭管道 CloseHandle(hPipe); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值