前面已经使用邮槽实现过进程间通信: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
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/228768
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!