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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM