博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++下使用命名管道实现进程间通信
阅读量:5234 次
发布时间:2019-06-14

本文共 3907 字,大约阅读时间需要 13 分钟。

  前面已经使用邮槽实现过进程间通信: ,这里使用命名管道实现进程间通信。

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

  ①创建命名管道,命名管道通过调用函数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 lpSecurityAttributes10 );

  各参数的设置方法可参考MSDN:

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

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

  参数的设置方法:

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

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

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

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

  服务器端:

1 //server 2 //命名管道采用基于连接的可靠传输方式,只能一对一传输 3 #include 
4 #include
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 else26 {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 else40 {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 
3 #include
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 else29 {30 if (::WriteFile(h_pipe, buf_msg, BUF_SIZE, &num_rcv, nullptr))31 {32 cout << "Message sent successfully...\n";33 }34 else35 {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

你可能感兴趣的文章
Java线程面试题
查看>>
C#2.0 读word的多个表格到DataGridView或是其它控件 XP Vista
查看>>
sql script: Graphs, Trees, Hierarchies and Recursive Queries
查看>>
Paper Reading: Relation Networks for Object Detection
查看>>
Android中点中overlay弹出带尾巴的气泡的实现
查看>>
Mybatis接口中传递多个参数
查看>>
Dreamweaver层使用八定律
查看>>
Java IO流学习总结
查看>>
day22 01 初识面向对象----简单的人狗大战小游戏
查看>>
数组的几种常用方法总结
查看>>
递归函数,二分运算,正则表达式
查看>>
阅读软件工程的问题
查看>>
【Netty】UDP广播事件
查看>>
(4)Numpy+矩阵计算+和生成
查看>>
ttt
查看>>
[置顶] java处理office文档与pdf文件(一)
查看>>
Flutter之内置动画(转)
查看>>
MySql优化相关概念的理解笔记
查看>>
sql索引影响数据存储位置的示例
查看>>
数据库解决方案
查看>>