C/S模型之命名管道
说明:利用管道实现服务端与客户端之间的交互。效果等同于利用socket。
命名管道(NamedPipe)是一种简单的进程间通信(IPC)机制,是服务器进程和一个或多个客户进程之间通信的单向或双向管道。
其本质是文件读写、内存共享。
采用命名管道完成进程通信的过程为:
1.在服务器端调用CreateNamedPipe创建命名管道之后,调用ConnectNamedPipe函数让服务器进程等待客户端进程连接到该命名管道的实例上。
2.在客户端,首先调用WaitNamedPipe函数判断当前是否有可以利用的命名管道实例,如果有就调用CreateFile函数打开该命名管道的实例,并建立一个连接。
之后就可以通过ReadFile、WriteFile进行通信。
函数讲解:
第一个CreateNamedPipe
函数功能:创建命名管道
函数原型:
HANDLEWINAPICreateNamedPipe(
LPCTSTRlpName,
DWORDdwOpenMode,
DWORDdwPipeMode,
DWORDnMaxInstances,
DWORDnOutBufferSize,
DWORDnInBufferSize,
DWORDnDefaultTimeOut,
LPSECURITY_ATTRIBUTESlpSecurityAttributes
);
参数说明:
第一个参数LPCTSTRlpName
表示管道名称,采用的形式是:\\.\pipe\pipename。最多可达256个字符的长度,而且不区分大小写。如果已经有同名管道,则会创建那个管道的一个新实例。
第二个参数DWORDdwOpenMode
表示管道的打开方式。下面列出最常用的三种,更多请参阅MSDN。
1.PIPE_ACCESS_DUPLEX
该管道是双向的,服务器和客户端进程都可以从管道读取或者向管道写入数据。
2.PIPE_ACCESS_INBOUND
该管道中数据是从客户端流向服务端,即客户端只能写,服务端只能读。
3.PIPE_ACCESS_OUTBOUND
该管道中数据是从服务端流向客户端,即客户端只能读,服务端只能写。
第三个参数DWORDdwPipeMode
表示管道的模式,下面是一些常用模式介绍,更多请参阅MSDN。
1.PIPE_TYPE_BYTE
数据作为一个连续的字节数据流写入管道。
2.PIPE_TYPE_MESSAGE
数据用数据块(名为“消息”或“报文”)的形式写入管道。
3.PIPE_READMODE_BYTE
数据以单独字节的形式从管道中读出。
4.PIPE_READMODE_MESSAGE
数据以名为“消息”的数据块形式从管道中读出(要求指定PIPE_TYPE_MESSAGE)。
5.PIPE_WAIT
同步操作在等待的时候挂起线程。
6.PIPE_NOWAIT
同步操作立即返回。
第四个参数DWORDnMaxInstances
表示该管道所能够创建的最大实例数量。必须是1到常数PIPE_UNLIMITED_INSTANCES间的一个值。
在WINBASE.H中有#define PIPE_UNLIMITED_INSTANCES 255
第五个参数DWORDnOutBufferSize
表示管道的输出缓冲区容量,为0表示使用默认大小。
第六个参数DWORDnInBufferSize
表示管道的输入缓冲区容量,为0表示使用默认大小。
第七个参数DWORDnDefaultTimeOut
表示管道的默认等待超时。
第八个参数LPSECURITY_ATTRIBUTESlpSecurityAttributes
表示管道的安全属性。
函数返回值:
函数执行成功返回命名管道的句柄,否则返回INVALID_HANDLE_VALUE。
第二个ConnectNamedPipe
函数功能:等待客户端连接命名管道
函数原型:
BOOLWINAPIConnectNamedPipe(
HANDLEhNamedPipe,
LPOVERLAPPEDlpOverlapped
);
函数说明:
第一个参数表示命名管道的句柄。
第二个参数是一个指向OVERLAPPED结构的指针,一般置为NULL就可以了。
第三个WaitNamedPipe
函数功能:客户端连接命名管道
函数原型:
BOOLWINAPIWaitNamedPipe(
LPCTSTRlpNamedPipeName,
DWORDnTimeOut
);
函数说明:
第一个参数LPCTSTRlpNamedPipeName
表示管道名称,采用的形式是:\\servername\pipe\pipename。如果是本机管道,servername用“.”来表示。
第二个参数DWORDnTimeOut
表示等待命名管道的一个实例有效的超时时间,单位毫秒。也可以用NMPWAIT_USE_DEFAULT_WAIT表示使用命名管道的设定值(在调用CreateNamedPipe创建命名管道时指定的),NMPWAIT_WAIT_FOREVER表示无限等待。
函数返回值:
在指定时间内连接成功返回TRUE,否则返回FALSE。
注意
1:如果指定名称的命名管道还没创建,函数立即返回,返回值为FALSE。
2:如果函数执行成功返回TRUE,表示至少有一个命名管道的实例有效,接下来应该使用CreateFile函数打开命名管道的一个句柄,但是CreateFile可能会打开管道失败,因为该实例有可能被服务端关闭或被已经被其他客户端打开。
服务端和客户端的主要步骤如下所示:
1. 服务端用CreateNamedPipe创建一个命名管道并使用ConnectNamedPipe等待客户端的连接。
2. 客户端使用WaitNamedPipe连接成功后,用CreateFile打开管道并使用WriteFile向管道中写入一段数据(即向服务端发送消息)。
3. 服务端使用ReadFile从管道中读取数据后(即收到消息)再向管道中写入确认信息表明已经收到客户端传输的数据(即通知客户端已收到)。
4. 客户端收到确认信息后结束,调用CloseHandle关闭管道(该管道是CreateFile打开的)。
5.服务端使用DisconnectNamedPipe和CloseHandle关闭管道。
源代码: //服务端 #include "stdafx.h"
#include <Windows.h> int _tmain(int argc, _TCHAR* argv[])
{
const char *szPipeName = "\\\\.\\pipe\\Pipe";
//创建命名管道
HANDLE hPipe = CreateNamedPipe(
szPipeName, // pipe name
PIPE_ACCESS_DUPLEX |
FILE_FLAG_OVERLAPPED, // read/write access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
MAXBYTE, // output buffer size
MAXBYTE, // input buffer size
, // client time-out
NULL); // default security attribute if (hPipe == INVALID_HANDLE_VALUE)
{
printf("CreateNamedPipe Error :%d", GetLastError());
} char pRecvBuf[MAXBYTE] = { };
DWORD dwLen=; //连接管道
if (ConnectNamedPipe(hPipe, NULL))
{
printf("连接成功,开始接收数据!\n");
while (true)
{
//取得客户端的数据
if (ReadFile(hPipe, pRecvBuf, MAXBYTE, &dwLen, ))
{
printf("%s\n", pRecvBuf);
} if (strcmp(pRecvBuf, "exit") == )
{
break;
} //将收到的数据进行返回
if (WriteFile(hPipe, pRecvBuf, strlen(pRecvBuf) + sizeof(char), &dwLen, ))
{ }
else
{
break;
}
}
}
// 关闭管道
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
return ;
}
//客户端 #include "stdafx.h"
#include <Windows.h> int _tmain(int argc, _TCHAR* argv[])
{
const char *szPipeName = "\\\\.\\pipe\\Pipe";
//检测是否存在该命名管道
if (WaitNamedPipe(szPipeName, NMPWAIT_WAIT_FOREVER) == TRUE)
{
printf("连接命名管道成功!\n");
} //打开文件--连接管道
HANDLE hFile = CreateFile(szPipeName, GENERIC_WRITE | GENERIC_READ, , NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); char pSendBuf[MAXBYTE] = { };
char pRecvBuf[MAXBYTE] = {};
DWORD dwLen = ; while (true)
{
gets_s(pSendBuf);
//将管道传数据
if(!WriteFile(hFile, pSendBuf, strlen(pSendBuf) + sizeof(char), &dwLen, NULL))
{
printf("False\n");
}
if (strcmp(pSendBuf, "exit") == )
{
break;
}
//读取管道中的数据
if (ReadFile(hFile, pRecvBuf, MAXBYTE, &dwLen, ))
{
printf("return :%s \n", pRecvBuf);
} } //关闭管道
CloseHandle(hFile);
return ;
}
C/S模型之命名管道的更多相关文章
- Windows进程间通信--命名管道
1 相关概述 命名管道(Named Pipes)是一种简单的进程间通信(IPC)机制.命名管道可以在同一台计算机的不同进程之间,或者跨越一个网络的不同计算机的不同进程之间的可靠的双向或单向的数据通信. ...
- UWP使用命名管道与桌面程序通信 (C#)
关于UWP的历史,其起源是Microsoft在Windows 8中引入的Metro apps.(后来又被称作Modern apps, Windows apps, Universal Windows A ...
- 【windows 操作系统】进程间通信(IPC)简述|无名管道和命名管道 消息队列、信号量、共享存储、Socket、Streams等
一.进程间通信简述 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进 ...
- 【说解】在shell中通过mkfifo创建命名管道来控制多个进程并发执行
背景: 工作中有两个异地机房需要传数据,数据全名很规范,在某个目录下命名为统一的前缀加上编号.如/path/from/file.{1..100}.而机房间的专线对单个scp进程的传输速度是有限制的,比 ...
- Windows进程间通信—命名管道
命名管道是通过网络来完成进程间的通信,它屏蔽了底层的网络协议细节.我们在不了解网络协议的情况下,也可以利用命名管道来实现进程间的通信.与Socket网络通信相比,命名管道不再需要编写身份验证的代码.将 ...
- Linux学习笔记(13)-进程通信|命名管道
匿名管道只能在具有亲属关系的进程间通信,那么如果想要在不具有亲戚关系,想在陌生人之间通信,那又该怎么办呢? 别慌,Linux身为世界上*强大的操作系统,当然提供了这种机制,那便是命名管道-- 所谓命名 ...
- Linux进程间通信(四):命名管道 mkfifo()、open()、read()、close()
在前一篇文章—— Linux进程间通信 -- 使用匿名管道 中,我们看到了如何使用匿名管道来在进程之间传递数据,同时也看到了这个方式的一个缺陷,就是这些进程都由一个共同的祖先进程启动,这给我们在不相关 ...
- [C++] socket -8 [命名管道]
::命名管道不但能实现同一台机器上两个进程通信,还能在网络中不同机器上的两个进程之间的通信机制.与邮槽不同,命名管道是采用基于连接并且可靠的传输方式,所以命名管道传输数据只能一对一进行传输. /* 命 ...
- SQL Server 连接问题圣经-命名管道
SQL Server 连接问题圣经-命名管道 (1) APGC DSD Team 12 Jan 2011 1:24 AM 3 一.前言 在使用SQL Server 的过程中,用户遇到的最多的莫过于连接 ...
随机推荐
- Windows正向绑定shell和反向反弹shell的Python代码
Windows下的shell原理 经过查阅资料,使用os.dup2(nfd, ofd)的方式重定向socket的输入输出到windows系统的cmd是无法做到的,属于系统原因,不能直接复制Linux下 ...
- web开发之Cookie使用
做过web开发的小伙伴对于Cookie一定不陌生,当用户登录后将用户的账号保存到本地,密码保存时,建议使用MD5进行加密,以防止用户个人信息的泄露.今天和大家简单聊聊关于Jquer Cookie的使用 ...
- Node.j中path模块对路径的操作
一.path模块 https://nodejs.org/docs/latest/api/path.html#path_path_join_paths 1.join方法 ==> 该方法将多个参数值 ...
- OpenMax概述
一.OpenMax简介 OpenMAX是一个多媒体应用程序的标准.由NVIDIA公司和Khronos™在2006年推出. 它是无授权费的.跨平台的C语言程序接口序列,这些接口对音频.视频.静态图片的常 ...
- EF---延迟加载技术
延迟加载: 优点:只在需要的时候加载数据,不需要预先计划,避免了各种复杂的外连接.索引.视图操作带来的低效率问题 使用方式:两步 第一:在需要延迟加载的属性前加上virtual ,该属性的类型可以是任 ...
- 数字模型制作规范(转自Unity3D群)
本文提到的所有数字模型制作,全部是用3D MAX建立模型,即使是不同的驱动引擎,对模型的要求基本是相同的.当一个VR模型制作完成时,它所包含的基本内容包括场景尺寸.单位,模型归类塌陷.命名.节点编辑, ...
- MONGOOSE – 让NODE.JS高效操作MONGODB(转载)
Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,类似ORM,Mongoose将数据库中的数据转换为JavaScript对象以供你在应用中使用. ...
- javascript中top、clientTop、scrollTop、offsetTop的讲解(转载加总结)
scrollHeight: 获取对象的滚动高度. scrollLeft:设置或获取位于对象左边界和窗口中目前可见内容的最左端之间的距离 scrollTop:设置或获取位于对象最顶端和窗口中可见内容的最 ...
- saltstack------安装篇
一.环境准备 系统:centos7 and centos6.8 IP 系统 172.16.1.10 centos7 172.16.1.11 centos7 172.16.1.21 centos6. ...
- 关于graham扫描法求凸包的小记
1.首先,凸包是啥: 若是在二维平面上,则一般的,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点. ───────────────────────────── ...