c++下使用命名管道实现进程间通信
前面已经使用邮槽实现过进程间通信:http://www.cnblogs.com/jzincnblogs/p/5192654.html ,这里使用命名管道实现进程间通信。
与邮槽不同的是,命名管道在进程间传输数据是基于连接且可靠的传输方式,所以命名管道传输数据只能一对一。使用命名管道的步骤如下:
①创建命名管道,命名管道通过调用函数CreateNamedPipe()创建,函数原型如下:
HANDLE WINAPI CreateNamedPipe(
_In_ LPCTSTR lpName,
_In_ DWORD dwOpenMode,
_In_ DWORD dwPipeMode,
_In_ DWORD nMaxInstances,
_In_ DWORD nOutBufferSize,
_In_ DWORD nInBufferSize,
_In_ DWORD nDefaultTimeOut,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes
);
各参数的设置方法可参考MSDN:https://msdn.microsoft.com/zh-cn/biztalk/aa365150(v=vs.80)
②连接命名管道。当用户成功创建命名管道后便可调用相关函数连接命名管道,对于服务器而言,可以调用函数ConnectNamedPipe()等待客户端的连接请求,函数原型如下:
BOOL WINAPI ConnectNamedPipe(
_In_ HANDLE hNamedPipe,
_Inout_opt_ LPOVERLAPPED lpOverlapped
);
参数的设置方法: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()完成,与上一篇的邮槽类似。
服务器和客户端的实现代码如下:
服务器端:
//server
//命名管道采用基于连接的可靠传输方式,只能一对一传输
#include <windows.h>
#include <iostream> #define BUF_SIZE 1024 using std::cerr;
using std::cout;
using std::endl; int main()
{
HANDLE h_pipe;
char buf_msg[BUF_SIZE];
DWORD num_rcv; //实际接收到的字节数
//创建命名管道,命名为MyPipe,消息只能从客户端流向服务器,读写数据采用阻塞模式,字节流形式,超时值置为0表示采用默认的50毫秒
h_pipe = ::CreateNamedPipe("\\\\.\\pipe\\MyPipe", PIPE_ACCESS_INBOUND, PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUF_SIZE, BUF_SIZE, , nullptr);
if (h_pipe == INVALID_HANDLE_VALUE)
{
cerr << "Failed to create named pipe!Error code: " << ::GetLastError() << "\n";
system("pause");
return ;
}
else
{
cout << "Named pipe created successfully...\n";
}
//等待命名管道客户端连接
if (::ConnectNamedPipe(h_pipe, nullptr))
{
cout << "A client connected...\n";
memset(buf_msg, , BUF_SIZE);
//读取数据
if (::ReadFile(h_pipe, buf_msg, BUF_SIZE, &num_rcv, nullptr))
{
cout << "Message received: " << buf_msg << "\n";
}
else
{
cerr << "Failed to receive message!Error code: " << ::GetLastError() << "\n";
::CloseHandle(h_pipe);
::system("pause");
return ;
}
}
::CloseHandle(h_pipe);
::system("pause");
return ;
}
客户端:
//client
#include <windows.h>
#include <iostream> #define BUF_SIZE 1024 using std::cerr;
using std::cout;
using std::endl; int main()
{
HANDLE h_pipe;
char buf_msg[] = "Test for named pipe...";
DWORD num_rcv; //实际接收到的字节数
cout << "Try to connect named pipe...\n";
//连接命名管道
if (::WaitNamedPipe("\\\\.\\pipe\\MyPipe", NMPWAIT_WAIT_FOREVER))
{
//打开指定命名管道
h_pipe = ::CreateFile("\\\\.\\pipe\\MyPipe", GENERIC_WRITE, , nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (h_pipe == INVALID_HANDLE_VALUE)
{
cerr << "Failed to open the appointed named pipe!Error code: " << ::GetLastError() << "\n";
::system("pause");
return ;
}
else
{
if (::WriteFile(h_pipe, buf_msg, BUF_SIZE, &num_rcv, nullptr))
{
cout << "Message sent successfully...\n";
}
else
{
cerr << "Failed to send message!Error code: " << ::GetLastError() << "\n";
::CloseHandle(h_pipe);
::system("pause");
return ;
}
}
::CloseHandle(h_pipe);
}
::system("pause");
return ;
}
c++下使用命名管道实现进程间通信的更多相关文章
- 命名管道实现进程间通信--石头、剪刀、布游戏 分类: linux 2014-06-01 22:50 467人阅读 评论(0) 收藏
下面这个程序利用命名管道实现进程间通信,模拟石头剪刀布游戏. 主进程为裁判进程,两个子进程为选手进程.裁判与选手间各建立一个命名管道. 进行100次出招,最后给出游戏胜负. #include < ...
- Linux进程间通信(四):命名管道 mkfifo()、open()、read()、close()
在前一篇文章—— Linux进程间通信 -- 使用匿名管道 中,我们看到了如何使用匿名管道来在进程之间传递数据,同时也看到了这个方式的一个缺陷,就是这些进程都由一个共同的祖先进程启动,这给我们在不相关 ...
- Linux进程间通信-命名管道
前面我们讲了进程间通信的一种方式,匿名管道.我们知道,匿名管道只能用于父子关系的进程之间.那么没有这种关系的进程之间该如何进行数据传递呢? 1.什么是命名管道 匿名管道是在缓存中开辟的输出和输入文件流 ...
- Linux系统编程——进程间通信:命名管道(FIFO)
命名管道的概述 无名管道,因为没有名字,仅仅能用于亲缘关系的进程间通信(很多其它详情.请看<无名管道>).为了克服这个缺点.提出了命名管道(FIFO).也叫有名管道.FIFO 文件. 命名 ...
- Linux进程间通信——使用命名管道
在前一篇文章——Linux进程间通信——使用匿名管道中,我们看到了如何使用匿名管道来在进程之间传递数据,同时也看到了这个方式的一个缺陷,就是这些进程都由一个共同的祖先进程启动,这给我们在不相关的的进程 ...
- Linux环境进程间通信(一):管道及命名管道
linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...
- 进程间通信系列 之 命名管道FIFO及其应用实例
进程间通信系列 之 概述与对比 http://blog.csdn.net/younger_china/article/details/15808685 进程间通信系列 之 共享内存及其实例 ...
- 【windows 操作系统】进程间通信(IPC)简述|无名管道和命名管道 消息队列、信号量、共享存储、Socket、Streams等
一.进程间通信简述 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进 ...
- Windows进程间通信—命名管道
命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节.我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信.与Socket网络通信相比,命名管道不再需要编写身份验证的代码.将 ...
随机推荐
- 20145312 实验五《Java网络编程》
20145312 实验五<Java网络编程> 一. 实验内容及要求 实验内容: 运行下载的TCP代码,结对进行,一人服务器,一人客户端: 利用加解密代码包,编译运行代码,一人加密,一人解密 ...
- 20145324 《Java程序设计》第10周学习总结
20145324 <Java程序设计>第10周学习总结 教材学习内容总结 1.网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输 2.在实际传输数据以前需要将域名转换为IP地 ...
- 单调队列:temperature
题目大意:某国进行了连续n天的温度测量,测量存在误差,测量结果是第i天温度在[l_i,r_i]范围内. 求最长的连续的一段,满足该段内可能温度不降. 第一行n下面n行,每行l_i,r_i 1<= ...
- c语言数组拷贝
#include <string.h> // 如果要从数组a复制k个元素到数组b,可以这样做 memcpy(b,a,sizeof(int)*k);
- 转:java 重定向和转发的区别
response.sendredirect("http://www.foo.com/path/error.html"); 重定向和转发有一个重要的不同:当使用转发时,JSP容器将使 ...
- JDK 中的监控与故障处理工具-05 (jstack)
jstack : stack trace for java jstack 命令用于生成虚拟机当前时刻的线程快照 (threaddump).线程快照是当前虚拟机中每一条线程正在执行的方法堆栈的集合,生成 ...
- 使用FireFox插件RESTClient工具POST方法?
下面尝试用Firefox的restclient,来调取api 当然需要打开火狐浏览器安装restclient的插件https://addons.mozilla.org/en-US/firefox/ad ...
- checkbox及css实现点击下拉菜单
面试遇到的问题.用checkbox中的:checked伪类选择器实现. 通过label标签来触发checkbox的unchecked 和checked两种状态:用css普通同胞选择器 ~.另外补充一点 ...
- go-statsd项目
linux命令: 进程:top 收包丢包:netstat -su[c持续输出] go tool pprof: 我们可以使用go tool pprof命令来交互式的访问概要文件的内容.命令将会分析指定的 ...
- HighCharts常用设置
1. X轴文字斜着放,在xAxis里设置 xAxis: { labels: { rotation: -90 //竖直放 rotation: -45 //45度倾斜 } } 2. 柱形图柱形的宽度和边框 ...