通过pipe进程间通信.docx
《通过pipe进程间通信.docx》由会员分享,可在线阅读,更多相关《通过pipe进程间通信.docx(14页珍藏版)》请在冰豆网上搜索。
![通过pipe进程间通信.docx](https://file1.bdocx.com/fileroot1/2022-11/15/f82e54c0-54aa-48bb-8609-d10510e0c754/f82e54c0-54aa-48bb-8609-d10510e0c7541.gif)
通过pipe进程间通信
基于visualc++之windows核心编程代码分析(17)通过pipe进程间通信
分类:
VC++编程技术VisualC++2010编程技术VisualStudio2012Windows8信息安全2011-12-1712:
17120人阅读评论(0)收藏举报
管道是一种用于在进程间共享数据的机制,其实质是一段共享内存。
Windows系统为这段共享的内存设计采用数据流I/0的方式来访问。
由一个进程读、另一个进程写,类似于一个管道两端,因此这种进程间的通信方式称作“管道”。
管道分为匿名管道和命名管道。
匿名管道只能在父子进程间进行通信,不能在网络间通信,而且数据传输是单向的,只能一端写,另一端读。
命令管道可以在任意进程间通信,通信是双向的,任意一端都可读可写,但是在同一时间只能有一端读、一端写。
管道客户端代码实现如下
viewplaincopytoclipboardprint?
1./* 头文件 */
2.#include
3.#include
4.#include
5.#include
6./* 常量 */
7.#define BUFSIZE 512
8./* ************************************
9.* int main(VOID)
10.* 功能 pipe 通信服务端主函数
11.**************************************/
12.int main(int argc, TCHAR *argv[])
13.{
14. HANDLE hPipe;
15. LPTSTR lpvMessage=TEXT("Default message from client");
16. TCHAR chBuf[BUFSIZE];
17. BOOL fSuccess;
18. DWORD cbRead, cbWritten, dwMode;
19. LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\samplenamedpipe");
20.
21. if( argc > 1 ) // 如果输入了参数,则使用输入的参数
22. lpvMessage = argv[1];
23. while
(1)
24. {
25. // 打开一个命名pipe
26. hPipe = CreateFile(
27. lpszPipename, // pipe 名
28. GENERIC_READ | GENERIC_WRITE, // 可读可写
29. 0, // 不共享
30. NULL, // 默认安全属性
31. OPEN_EXISTING, // 已经存在(由服务端创建)
32. 0, // 默认属性
33. NULL);
34. if (hPipe !
= INVALID_HANDLE_VALUE)
35. break;
36.
37. // 如果不是 ERROR_PIPE_BUSY 错误,直接退出
38. if (GetLastError() !
= ERROR_PIPE_BUSY)
39. {
40. printf("Could not open pipe");
41. return 0;
42. }
43.
44. // 如果所有pipe实例都处于繁忙状态,等待2秒。
45. if (!
WaitNamedPipe(lpszPipename, 2000))
46. {
47. printf("Could not open pipe");
48. return 0;
49. }
50. }
51.
52. // pipe已经连接,设置为消息读状态
53. dwMode = PIPE_READMODE_MESSAGE;
54. fSuccess = SetNamedPipeHandleState(
55. hPipe, // 句柄
56. &dwMode, // 新状态
57. NULL, // 不设置最大缓存
58. NULL); // 不设置最长时间
59. if (!
fSuccess)
60. {
61. printf("SetNamedPipeHandleState failed");
62. return 0;
63. }
64.
65. // 写入pipe
66. fSuccess = WriteFile(
67. hPipe, // 句柄
68. lpvMessage, // 写入的内容
69. (lstrlen(lpvMessage)+1)*sizeof(TCHAR), // 写入内容的长度
70. &cbWritten, // 实际写的内容
71. NULL); // 非 overlapped
72. if (!
fSuccess)
73. {
74. printf("WriteFile failed");
75. return 0;
76. }
77.
78. do
79. {
80. // 读回复
81. fSuccess = ReadFile(
82. hPipe, // 句柄
83. chBuf, // 读取内容的缓存
84. BUFSIZE*sizeof(TCHAR), // 缓存大小
85. &cbRead, // 实际读的字节
86. NULL); // 非 overlapped
87.
88. if (!
fSuccess && GetLastError() !
= ERROR_MORE_DATA)
89. break; //失败,退出
90.
91. _tprintf( TEXT("%s\n"), chBuf ); // 打印读的结果
92. } while (!
fSuccess); // ERROR_MORE_DATA 或者成功则循环
93.
94. getch();//任意键退出
95. // 关闭句柄
96. CloseHandle(hPipe);
97. return 0;
98.}
管道服务端代码实现如下,
viewplaincopytoclipboardprint?
1./* 头文件 */
2.#include
3.#include
4.#include
5./* 常量 */
6.#define PIPE_TIMEOUT 5000
7.#define BUFSIZE 4096
8./* 结构定义 */
9.typedef struct
10.{
11. OVERLAPPED oOverlap;
12. HANDLE hPipeInst;
13. TCHAR chRequest[BUFSIZE];
14. DWORD cbRead;
15. TCHAR chReply[BUFSIZE];
16. DWORD cbToWrite;
17.} PIPEINST, *LPPIPEINST;
18./* 函数声明 */
19.VOID DisconnectAndClose(LPPIPEINST);
20.BOOL CreateAndConnectInstance(LPOVERLAPPED);
21.BOOL ConnectToNewClient(HANDLE, LPOVERLAPPED);
22.VOID GetAnswerToRequest(LPPIPEINST);
23.VOID WINAPI CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED);
24.VOID WINAPI CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED);
25./* 全局变量 */
26.HANDLE hPipe;
27./* ************************************
28.* int main(VOID)
29.* 功能 pipe 通信服务端主函数
30.**************************************/
31.int main(VOID)
32.{
33. HANDLE hConnectEvent;
34. OVERLAPPED oConnect;
35. LPPIPEINST lpPipeInst;
36. DWORD dwWait, cbRet;
37. BOOL fSuccess, fPendingIO;
38.
39. // 用于连接操作的事件对象
40. hConnectEvent = Crea