IPC之命名管道

1.管道是通过IO接口存取得字节流, windows中利用得是ReadFile()和WriteFile(),windows利用单一句柄支持双向IO,命名管道也称做FIFO(first in first out)
命名管道得机制:一个进程把数据放到管道里,另一个知道管道名字得进程把数据把取走,实际是用于进程间通信得一段共享内存,创建管道得进程称为管道服务器,链接到一个管道得进程为管道客户机,用以下函数 

 

 管道实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连
接到- 一个管道的进程为管道客户机。可以用以下函数创建管道,即
HANDLB CreateNamedPipel
LPCTSTR IpName,
DWORD dwopenMode,
DWORD dwPipeMode,
DWORD nMaxInstances,
DWORD nOutBufferSi ze,
DWORD nInBufferSize,
DWORD nDefaultrimeOut,
LPSECURITY,ATTRIBUTES 1pSecurityAttributes
);
其中参数的含义如F:
IpName: 管道名称。用下面的方法命名;
每一一个命名管道都有一一个唯一的名字以区分存在于系统的命名对象列表中的其他命
名管道。管道服务器在调用CreateNamedPipe()创建命名管道的一一个或多个实例时为其指
定了名称。对于管道客户机,则是在调用CreateFile()或CallINamedPipe()函数以连接一
个命名管道实例时对管道名进行指定。命名管道的命名规范与以后介绍的邮槽有些类似,
对其标识也是采用的UNC 格式:
\\[uploading.4e448015.gif转存失败重新上传取消host.name 

]\Pipe\[Path]Name
其中,第- 一部分“\[host_name]”指定了服务器的名字,命名管道服务即在此服务
器创建,其字符串部分可表示为一一个小数点(表示本机)、星号(当前网络字段)、域名
或是一一个真 正的服务; 第二部分“Pipe”与邮槽的“Mailslot”
样是一一个不可变化的
硬编码字符串,以表示该文件是从属于NPFS; 第三部分“[Path]Name" 则使应用程序
可以唯一-定义及标识- 一个命名管道的名字,而且可以设置多级目录。
dwOpenMode: 管道建方式。可以是下面值的组合:
> PIPE ACCESS INBOUND: 管道只能用作接收数据。
4
PIPE ACCESS _OUTBOUND: 管道只能用作发送数据。
PIPE.ACCESS_ DUPLEX: 管道既可以发送也可以接收数据。
上面这三三个值只能够取其中- 一个,同时也可包括以下的- 一个或两个标识:
管道用于同步发送和接收数据,在系统内部
FILE FLAG WRITE THROUGH:
对于命名管道的处理上不经缓冲区并能直接发送,并且只有在数据被发送到目
标地址时发送函数才会返回。如果不设置这个参数,那么需要在数据积累到一
定量时才发送,并且对于发送函数的调用会马上返回。

 > FILE FLAG OVERLAPPED: 管道可以用于异步输入和输出,异步读写的有关
方法和文件异步读写是相同的。
dwPipeMode: 命名管道模式。可以是下面值的组合:
> PIPE_TYPE_BYTE: 数据在通过管道发送时作为字节流发送,不能与
PIPE READMODE MESSAGE 共用。
PIPE.TYPE.MESSAGE: 数据在通过管道发送时作为消息发送,不能与
PIPE READMODE BYTE 共用。
IPE_READMODE_BYTE: 在接收数据时接收字节流。

PIPE_READMODE_MESSAGE: 在接收数据日接收消息。
IPE _WAIT: 使用等待模式,在读、写和建立连接时都需要管道的另- -方完成相

应动作后才会返回。
IPE NOWAIT: 使用#I 等待模式,在读、写和建立连接时不需要管道的另- 一方
完成相应动作后就会立即返回。
该管道最大的实例数量。在第- 一次建立服务器方管道时这个参数表
nMaxInstances:
明该管道可以同时存在的数量。PIPE UNLIMITED INSTANCES 表明不对数量进行
限制。
nOutBufferSize 和nnBufferSize: 输出和输入缓冲区大小。
nDefaultTimeOut: 指定默认的超时时间(以亳秒为单位),如果在创建时设置为
NMPWAIT.USE DEFAULT.WAIT 表明无限制的等待,而以后服务器方的其他管道实例
也需要设置相同的值。
lpSecurtytltrbutes: 描述安全信息的一一个结构,一般设置为NULL。如果创建或打
开失败则返回INVALID HANDLE VALUE。可以通过GetLastErrort0得到错误信息。
其他管道函数简介如下所述。
CallNamedPipeO: 连接到一个命名管道,读取或写入数据之后关闭它。
ConnectNamedPipeQ: 服务进程准备好一个连接到客户进程的管道,并等待一
个客户进程连接上为止。
DiscocctNamedPipc: 服务端用来断开与客户端的连接。
GetNamedPipeHandleta 获取一个命名管道的状态信息。
获取一个命名管道的信息。
GetNamedPipeInfoO
PeekNamedPipeO: 从一个匿名或命名管道中复制数据到一个缓冲区。
SetNamedPipeHandleStat 设置管道的类型及其他状态信息,比如说是比特
流还是消息流管道。
TransactNamedPipeO: 从一 个消息管道读 息或向其 写入肖息。
WaitNamedPipeO:使服务器进程等待来自客户的实例连接。
 

 

2.命名管道服务端与客户端之间通信的实现流程:

 -- -4.2.2
命名管道服务端与客户端之间通信的实现流程一
(1) 连接建立
使用消息管道、邮槽和套接字通信
服务端通过函数CreateNamedPipe()创建- 一个命名管道的实例并返回用于今后操作
的句柄,或为已存在的管道创建新的实例。如果在已定义超时值变为0 以前,有一一个实
例管道可以使用,则创建成功并返回管道句柄,并用以侦听来自客户端的连接请求,该
功能通过ConneclNamedPipe(实现。
另- 一方面,客户端通过函数WaitINamedPipe()使服务进程等待来自客户的实例连接。
如果在超时值变为0以前,有一一个管道可以为连接使用,则WaitNamedPipe()返回TRUE,
并通过调用CreateFile()或CallINamedPipe()来呼叫对服务端的连接。此时服务端将接受客
户端的连接请求,成功建立连接,服务端ConnectNamedPipe(返回TRUE,客户端
CreatcFile()返回- 一个指向管道文件的句柄。
从时序上讲,首先是客户端通过WaitNamedPipe()使服务端的CreateFile()在限定时间
内创建实例成功,然后双方通过ConnectNamedPipe()和CreateFile()成功连接,并返回用
于通信的文件句柄,此时双方即可进行通信。
(2) 通信实现
建立连接之后,客户和服务端可以通过得到的管道文件句柄利用ReadFile()和
WriteFile()进行彼此间的信息交换。
(3) 连接终止
当客户端与服务端的通信结束,或由于某种原因一一方需要断开时,客户端应调用
CloseFile(),而服务端应接着调用DisconnectNamedPipe。当然服务端亦可通过单方面
调用DisconnectNamedPipe()终止连接。最后应调用CloseHandle()来关闭该管道。
 

 

 

Server端 (1.启动服务 创建管道和事件2.创建线程负责与客户端通信(利用IO重叠与创建的事件联系)。3.接收客户端数据做出计算再反馈到客户端)
一 启动服务StartServer
1.创建管道的名字 CString PipeFullPathData = L"\\\\.\\Pipe\\NamedPipePipe";
2.创建管道 分配事件(因为是NamePipe),通过线程来通信
3.代码
void CServerDlg::OnBnClickedButtonStartServer()
{
UpdateData(TRUE);
CString PipeFullPathData = L"\\\\.\\Pipe\\NamedPipePipe";


if (m_CEdit_Max_Connect_Count > 0 && m_CEdit_Max_Connect_Count < 100)
{
for (UINT i = 0; i < m_CEdit_Max_Connect_Count; i++)
{
// 创建管道实例
m_UserData[i].PipeHandle = CreateNamedPipe(PipeFullPathData, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, \
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, m_CEdit_Max_Connect_Count, 0, 0, 1000, NULL);
if (m_UserData[i].PipeHandle == INVALID_HANDLE_VALUE)
{
DWORD ErrorCode = GetLastError();
this->MessageBox(L"创建管道错误!");
return;
}
// 为每个管道实例创建一个事件对象,用于实现重叠IO
m_UserData[i].EventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
// 为每个管道实例分配一个线程,用于响应客户端的请求
m_UserData[i].ThreadHandle = AfxBeginThread(ThreadProcedure, &m_UserData[i], THREAD_PRIORITY_NORMAL);
}

{
this->SetWindowText(L"命名管道—服务器(运行)");
this->MessageBox(L"服务启动成功");
}
}
}
事件线程函数(利用的是IO重叠)注意的是BufferData的传入 两个或多个数据的传入这样做

UINT ThreadProcedure(LPVOID ParameterData)
{
DWORD ReturnLength = 0;
char BufferData[0x400] = { 0 };

USER_DATA UserData = *(USER_DATA*)ParameterData;
OVERLAPPED Overlapped = { 0, 0, 0, 0, UserData.EventHandle};

while (1)
{
memset(BufferData, 0, sizeof(BufferData));
// 命名管道的连接函数,等待客户端的连接(只针对NT)
ConnectNamedPipe(UserData.PipeHandle, &Overlapped);

// 实现重叠I/0,等待OVERLAPPED结构的事件对象
WaitForSingleObject(UserData.EventHandle, INFINITE);

// 检测I/0是否已经完成,如果未完成,意味着该事件对象是人工设置,即服务需要停止
if (!GetOverlappedResult(UserData.PipeHandle, &Overlapped, &ReturnLength, true))
break;
// 从管道中读取客户端的请求信息
if (!ReadFile(UserData.PipeHandle, BufferData, 0x400, &ReturnLength, NULL))
{
MessageBox(0, L"读取管道错误!", 0, 0);
break;
}
int v1, v2;
sscanf(BufferData, "%d %d", &v1, &v2); //字符串转换为%d
__ServerDlg->m_v1 = v1;
__ServerDlg->m_v2 = v2;
__ServerDlg->m_v3 = v1 + v2;
memset(BufferData, 0, sizeof(BufferData));
sprintf(BufferData, "%d", __ServerDlg->m_v3);//从客户端到主控端出现
// 把反馈信息写入管道
WriteFile(UserData.PipeHandle, BufferData, strlen(BufferData), &ReturnLength, NULL);
__ServerDlg->SetDlgItemInt(IDC_EDIT_V1, v1, true);
__ServerDlg->SetDlgItemInt(IDC_EDIT_V2, v2, true);
__ServerDlg->SetDlgItemInt(IDC_EDIT_V3, __ServerDlg->m_v3, true);
// 断开客户端的连接,以便等待下一客户的到来
DisconnectNamedPipe(UserData.PipeHandle);
}

return 0;
}

关闭服务
void CServerDlg::OnBnClickedButtonStopServer()
{

DWORD dwNewMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT;
for (UINT i = 0; i < m_CEdit_Max_Connect_Count; i++)
{
// 设置重叠I/O的事件,使得工作线程安全结束
SetEvent(m_UserData[i].EventHandle);
Sleep(1);
CloseHandle(m_UserData[i].ThreadHandle);
CloseHandle(m_UserData[i].PipeHandle);
}

this->SetWindowText(L"命名管道—服务器(停止)");
this->MessageBox(L"停止启动成功");
}

Client端(提交数据到主控端,主控端反馈最终结果到客户端)
void CClientDlg::OnBnClickedButtonSubmitClient()
{
// TODO: 在此添加控件通知处理程序代码

HANDLE NamedPipeHandle = CreateFile(L"\\\\.\\Pipe\\NamedPipePipe", GENERIC_READ | GENERIC_WRITE, \
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (NamedPipeHandle == INVALID_HANDLE_VALUE)
{
this->MessageBox(L"打开管道失败,服务器尚未启动,或者客户端数量过多");
return;
}

DWORD ReturnLength = 0;
char BufferData[0x400] = { 0 };
// 把两个整数(a,b)格式化为字符串

m_v1 = GetDlgItemInt(IDC_EDIT_V1);
m_v2 = GetDlgItemInt(IDC_EDIT_V2);
sprintf(BufferData, "%d %d", this->m_v1, this->m_v2);//v1,v2写入数组
// 把数据写入管道
WriteFile(NamedPipeHandle, BufferData, strlen(BufferData), &ReturnLength/*写入地*/, NULL);

memset(BufferData, 0,0x400);//清空
// 服务器反馈后,读取服务器的反馈信息
ReadFile(NamedPipeHandle, BufferData, 0x400, &ReturnLength, NULL);
sscanf(BufferData, "%d", &(this->m_v3));//Client写入 Server输出
/*因为是客户端做运算,然后主控端响应再反馈*/
SetDlgItemInt(IDC_EDIT_V3, m_v3, true);

CloseHandle(NamedPipeHandle);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438159.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

REVERSE-PRACTICE-BUUCTF-17

REVERSE-PRACTICE-BUUCTF-17[网鼎杯 2020 青龙组]jocker[2019红帽杯]childRE[MRCTF2020]PixelShooter[ACTF新生赛2020]SoulLike[网鼎杯 2020 青龙组]jocker exe程序&#xff0c;运行后提示输入flag&#xff0c;无壳&#xff0c;用ida分析 main函数平衡栈后&#xff0c;F5反汇编…

Excluding Files From Team Foundation Version Control Using .tfignore Files

At one point I was coding on a hobby project, using Visual Studio Online for project management and source control. Because of the technologies involved, a large number of temporary files were being generated that I didn’t want checked in. Visual Studio’…

REVERSE-PRACTICE-BUUCTF-18

REVERSE-PRACTICE-BUUCTF-18[SWPU2019]ReverseMe[FlareOn1]Bob Doge[FlareOn5]Ultimate Minesweeper[GKCTF2020]Chellys identity[SWPU2019]ReverseMe exe程序&#xff0c;运行后提示输入flag&#xff0c;输入错误打印“Try again”&#xff0c;无壳&#xff0c;ida分析 交叉引…

VS2008中Web Reference和Service Reference的区别

很早就发现在vs2008中应用web service有两种方式&#xff0c;即Add Web Reference和Add Service Reference&#xff0c;但是一直不是很清楚这两者有什么区别。趁着今天有空实验一下这两者的区别并记录下来供大家参考。 首先在网上查找&#xff0c;发现有如下两个主要区别&#…

REVERSE-PRACTICE-BUUCTF-19

REVERSE-PRACTICE-BUUCTF-19[RoarCTF2019]polyre[安洵杯 2019]game[SCTF2019]Strange apk[CFI-CTF 2018]IntroToPE[RoarCTF2019]polyre elf文件&#xff0c;无壳&#xff0c;用ida分析 main函数的结构&#xff0c;多重循环&#xff0c;是控制流平坦化&#xff0c;参考&#xf…

REVERSE-PRACTICE-BUUCTF-20

REVERSE-PRACTICE-BUUCTF-20[SCTF2019]creakme[网鼎杯 2020 青龙组]bang[WUSTCTF2020]funnyreDig the way[SCTF2019]creakme exe程序&#xff0c;运行后提示输入ticket&#xff0c;无壳&#xff0c;用ida分析 交叉引用字符串“please input your ticket:”来到sub_402540函数 …

Web Reference和Service Reference的区别

今天因为项目需要使用服务引用&#xff0c;就按之前的经验添加上了&#xff0c;步骤如下&#xff1a; 项目根目录——引用——右键——添加服务引用——高级——添加Web引用——输入接口的URL地址——回车&#xff08;下方出现的就是接口的定义的方法&#xff09;——修改Web引…

REVERSE-PRACTICE-BUUCTF-21

REVERSE-PRACTICE-BUUCTF-21[SCTF2019]babyre[MRCTF2020]EasyCpp[GUET-CTF2019]encrypt[QCTF2018]Xman-babymips[SCTF2019]babyre elf文件&#xff0c;无壳&#xff0c;用ida分析 在start函数中看到main函数的字样&#xff0c;但是左侧函数窗没有找到main函数 原因是main函数中…

原型设计工具——“墨刀”的介绍与基本教程

一、产品介绍 &#xff08;1&#xff09;产品简介&#xff1a; 墨刀是一款在线原型设计与协同工具&#xff0c;借助墨刀&#xff0c;产品经理、设计师、开发、销售、运营及创业者等用户群体&#xff0c;能够搭建为产品原型&#xff0c;演示项目效果。 &#xff08;2&#xf…

MockPlus原型设计介绍

在第八周的课堂上&#xff0c;王文娟老师在校园系统上发布了对于自行选择的原型设计软件进行资料查找以及自学的任务。因为之前的课程学习需要&#xff0c;我们已经大概掌握了原型设计软件Axure的使用&#xff0c;因此在这里&#xff0c;我选择了另一原型设计进行介绍&#xff…

REVERSE-PRACTICE-BUUCTF-22

REVERSE-PRACTICE-BUUCTF-22[SCTF2019]Who is he[FlareOn2]very_success[NPUCTF2020]Baby Obfuscation[HDCTF2019]MFC[SCTF2019]Who is he unity游戏&#xff0c;运行后输入&#xff0c;点击按钮检验输入 dnSpy打开Who is he\Who is he_Data\Managed\Assembly-CSharp.dll 在Te…

浅谈常见的NoSQL技术方案和选型

前言 在互联网和大数据的背景下&#xff0c;越来越多的网站、应用系统需要支撑 海量数据存储、高并发请求、高可用、高可扩展性 等特性要求。传统的 关系型数据库 已经难以应对类似的需求&#xff0c;各种各样的 NoSQL&#xff08;Not Only SQL&#xff09;数据库因此而产生。…

REVERSE-PRACTICE-BUUCTF-23

REVERSE-PRACTICE-BUUCTF-23[2019红帽杯]Snake[BSidesSF2019]blink[De1CTF2019]Re_Sign[ACTF新生赛2020]Splendid_MineCraft[2019红帽杯]Snake unity游戏&#xff0c;dnSpy打开Snake\Snake_Data\Managed\Assembly-CSharp.dll 发现要载入Interface这个dll ida打开Snake\Snake_…

REVERSE-PRACTICE-BUUCTF-24

REVERSE-PRACTICE-BUUCTF-24[watevrCTF 2019]Timeout[SUCTF2019]hardcpp[CISCN2018]2ex[UTCTF2020]babymips[watevrCTF 2019]Timeout elf文件&#xff0c;无壳&#xff0c;ida分析 main函数中signal&#xff0c;alarm&#xff0c;delay三个函数配合使用是为了反调试 交叉引用…

REVERSE-PRACTICE-BUUCTF-25

REVERSE-PRACTICE-BUUCTF-25特殊的 BASE64[FlareOn1]Javascrap[WMCTF2020]easy_re[NPUCTF2020]BasicASM特殊的 BASE64 exe程序&#xff0c;运行后输入&#xff0c;无壳&#xff0c;ida分析 main函数&#xff0c;读取输入&#xff0c;进行变表base64编码&#xff0c;与rightFla…

REVERSE-PRACTICE-BUUCTF-26

REVERSE-PRACTICE-BUUCTF-26[FlareOn6]FlareBear[SUCTF2018]babyre[GKCTF2020]WannaReverse[FlareOn4]greek_to_me[FlareOn6]FlareBear apk文件&#xff0c;模拟器上运行&#xff0c;创建一个小熊&#xff0c;有三种方式交互&#xff0c;分别为“吃饭”&#xff0c;“篮球”以…

C#的变迁史02 - C# 2.0篇

在此重申一下&#xff0c;本文仅代表个人观点&#xff0c;如有不妥之处&#xff0c;还请自己辨别。 第一代的值类型装箱与拆箱的效率极其低下&#xff0c;特别是在集合中的表现&#xff0c;所以第二代C#重点解决了装箱的问题&#xff0c;加入了泛型。1. 泛型 - 珍惜生命&#x…

REVERSE-PRACTICE-BUUCTF-27

REVERSE-PRACTICE-BUUCTF-27[XMAN2018排位赛]Dragon Quest[羊城杯 2020]easyre[watevrCTF 2019]Repyc[2019红帽杯]calc[XMAN2018排位赛]Dragon Quest elf文件&#xff0c;无壳&#xff0c;ida分析 main函数&#xff0c;读取输入&#xff0c;start_quest函数验证输入&#xff0…

C#的变迁史03 - C# 3.0篇

C# 3.0 (.NET 3.5, VS2008) 第三代C#在语法元素基本完备的基础上提供了全新的开发工具和集合数据查询方式&#xff0c;极大的方便了开发。 1. WPF&#xff0c;WCF&#xff0c;WF 这3个工程类型奠定了新一代.NET开发的客户端模型&#xff0c;通信模型&#xff0c;工作流模型。 …

REVERSE-PRACTICE-BUUCTF-28

REVERSE-PRACTICE-BUUCTF-28[FlareOn6]Memecat Battlestation[b01lers2020]chugga_chugga[INSHack2018]Tricky-Part1[watevrCTF 2019]esreveR[FlareOn6]Memecat Battlestation .Net程序&#xff0c;运行后输入weapon code&#xff0c;用dnSpy打开 在Stage1Form直接找到第一个w…