使用命名管道实现进程通信

实验四:使用命名管道实现进程通信

一、实验目的

  1. 了解windows系统环境下的进程通讯机制。
  2. 熟悉Windows系统提供的进程通信API。

二、实验准备

相关API函数介绍

建立命名管道

函数CreateNamePipe()创建一个命名管道实例,并返回该管道的句柄。

原型:

    HANDLE CreateNamePipe(
    LPCTSTR lpName,                     //命名管道的名字
    DWORD dwOpenMode,                 //命名管道的访问模式
    DWORD dwPipe’Mode,                 //命名管道的模式
    DWORD nMaxInstances,                //可创建实例的最大值
    DWORD nOutBufferSize,                //以字节为单位的输出缓冲区的大小
    DWORD nInBufferSize,                //以字节为单位的输入缓冲区的大小
    DWORD nDefaultTimeOut,               //默认超时时间
    LPSECURITY_ATTRIBUTES lpSecurityAttributes         //安全属性
    );

参数说明:

  • lpName:为命名管道的名字,管道的命名方式为\\ServerName\pipe\pipename,其中ServerName为用命名管道通信时服务器的主机名或IP地址,pipename为命名管道的名字,用户可自行定义。
  • dwOpenMode:指出命名管道的访问模式。模式如表2-5所示。
  • dwPipeMode:指出管道的模式。模式如表2-6所示、
  • nMaxInstances:该命名管道可以创建实例的最大值。
  • nOutBufferSize:输出缓冲区的大小,以字节为单位。
  • nInBufferSize:输入缓冲区的大小,以字节为单位。
  • nDefaultTimeOut:默认的超时时间,以ms为单位。如果函数WaitNamePipe()指出- NMWAIT_USE_DEFAULT_WAIT,每个管道实例必须指定同一值的名字。
  • lpSecurityAttributes:为管道指定安全属性,为NULL时,管道得到一个默认的安全描述符。

返回值:
如果管道创建成功,将返回服务器命名管道实例的句柄。如果失败,返回INVALID_HANDLE_VALUE,可以调用函数GetLastError()查询失败的原因;当返回ERROR_INVALID_PARAMETER时,表明参数nMaxInstances指定的值大于PIPE_UNLIMTED_INSTANCES。
连接命名管道
服务器用函数ConnectNamePipe()连接命名管道。创建后命名管道也等待客户端的连接,客户端可以使用函数CreateFile()和CallNamedPipe()进行连接。
原型:

BOOL ConnectNamedPipe(
HANDLE hNamePipe,          //命名管道实例句柄
LPOVERLAPPED lpOver lapped        //指向Overlapped结构的指针
);

参数说明:
hNamedPipe:为命名管道创建时得到的一个命名管道实例句柄。
lpOverlapped:指向Overlapped结构的指针,可设其为NULL。
返回值:
成功,将返回一个非0值;失败,系统返回0,可以调用函数GetLastError()查询失败的原因。
拆除命名管道的连接
函数DisconnectNamePipe()拆除命名管道服务器与客户端的连接。
原型:

BOOL DisconnectNamePipe(
HANDLE hNamePipe
);

参数说明:
hNamedPipe:为命名管道创建时得到的一个命名管道实例句柄。
返回值:
成功,将返回一个非0值;失败,系统返回0,可以调用函数GerLasrError()查询失败的原因。
客户端连接服务器已建立的命名管道
客户端使用函数CallNamePipe()连接服务器建立的命名管道。
原型:

BOOL CallNamePipe(
   LPCTSTR lpNamePipeName,           //命名管道的名字
   LPVOID lpInBuffer,                  //输出数据缓冲区
   DWORD nInBufferSize,              //以字节为单位的输出数据缓冲区的大小
   LPVOID lpOurBuffer,                //输入数据缓冲区指针
   DWORD nOurBufferSize,           //以字节为单位的输入数据缓冲区的大小
   LPDWORD lpBytesRead,              //输入字节数指针
   DWORD nTimeOUT                  //等待时间
);

参数说明:
lpNamedPipeName:命名管道的名字。
lpInBuffer:指出用于输出数据(向管道写数据)的缓冲区指针。
nInBufferSize:用于输出数据缓冲区的大小,以字节为单位。
lpOutBuffer:指出用于接收数据(从管道读出数据)的缓冲区指针。
nOutBufferSize:指向用于接收数据缓冲区的大小,以字节为单位。
lpBytesRead:一个32位的变量,改变量用于存储从管道读出的字节数。
nTimeOut:等待命名管道成为可用状态的时间,单位为ms。
返回值:
成功,将返回一个非0值;失败,系统返回0,可用调用函数GetLastError()查询失败的原因。
客户端等待命名管道
客户端使用函数WaitNamedPipe()等待服务器连接命名管道。
原型:
BOOL WaitNamedPipe(
LPCTSTR lpNamedPipeName, //要等待的命名管道名
DWORD nTimeOut //等待时间
);
参数说明:
lpNamedPipeName:要等待的命名管道的名字。
nTimeOut:等待命名管道成为可用状态的时间,单位为ms.
返回值:
在等待时间内要连接的命名管道可以使用,将返回一个非0值。在等待时间内要连接的命名管道不可以使用,系统返回0,可用调用GetLastError()查询失败的原因。

三、实验内容

(一)实验内容

  • 使用Windows系统提供的命名管道完成两个进程之间的通信,能正确使用创建命名管道CreateNamePipe(),连接命名管道ConnectNamePipe(),拆除命名道的连接DisconnectNamePipe(),连接服务器已建立的命名管道CallNamePipe(),等待命名管道WaitNamedPipe()等API.
  • 在客户端输入信息传入服务器,再从服务器输入信息传入客户端。

(二)主要代码

服务器的代码

// PipeServe.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "PipeServe.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Dart 是 Google 开发的编程语言,可以用来开发移动应用和 web 应用。命名管道是 UNIX 系统中的一种 IPC(进程通信)方式,可以在不同进程之间传递数据。在 Dart 中,可以使用 dart:io 库中的 NamedPipe 类来操作命名管道。 下面是一个简单的 Unix 示例,演示了如何在两个不同的 Dart 程序之间使用命名管道进行通信: 程序1(sender.dart) ```dart import 'dart:io'; main() async { var pipe = await NamedPipeServer.create('/tmp/my_pipe'); var sink = pipe.sink; sink.write('Hello from sender!'); await sink.flush(); await sink.close(); } ``` 程序2(receiver.dart) ```dart import 'dart:io'; main() async { var pipe = await NamedPipeClient.connect('/tmp/my_pipe'); var input = pipe.input; var message = await input.read(); print(message); await input.close(); } ``` 在这个示例中,程序 1 使用 NamedPipeServer.create() 创建了一个名为 /tmp/my_pipe 的命名管道,并向其中写入了一条消息 "Hello from sender!"。程序 2 使用 NamedPipeClient.connect() 连接到了同一个命名管道,并从中读取了消息,最后打印出来。 ### 回答2: Dart是一种跨平台的编程语言,支持在不同的操作系统上进行开发。在Unix系统中,进程通信是一个非常重要的概念。命名管道是一种用于在不同进程之间进行通信的机制。 在Dart中,可以使用dart:io包来实现使用命名管道进行进程通信的功能。首先,需要创建一个命名管道。可以使用File类的static方法mkfifo来创建一个命名管道文件。 具体示例代码如下: import 'dart:io'; void main() { String pipePath = './mypipe'; // 命名管道的文件路径 Process.start('mkfifo', [pipePath]).then((Process process) { print('命名管道已创建'); // 接下来可以进行进程通信的操作 }); } 上面的示例代码中,首先使用Process.start方法调用mkfifo命令来创建一个命名管道文件,然后通过then回调函数来监听创建命名管道的结果,并在命名管道创建成功后进行进一步的处理。 在创建命名管道后,就可以使用命名管道进行进程通信了。可以使用File类来打开命名管道,并进行读写操作。具体的进程通信的操作可以根据需求进行自定义。 需要注意的是,使用命名管道进行进程通信时,需要确保读、写操作的顺序正确,以避免出现阻塞的情况。此外,命名管道也可以用于进程间的同步操作,例如等待另一个进程完成某个指定的任务后再进行下一步操作。 总而言之,Dart可以通过使用dart:io包来实现在Unix系统中使用命名管道进行进程通信的功能。通过创建命名管道文件,然后使用File类打开该文件进行读写操作,可以实现不同进程之间的通信与同步。具体的操作可以根据需求进行自定义。 ### 回答3: 在Unix系统中,进程通信是非常重要的,为了实现进程间的数据传递,可以使用命名管道。Dart语言也提供了类似的方法来实现进程通信命名管道是一种特殊的文件,它可以用来实现进程间的读写操作。在Unix示例中,首先我们需要创建一个命名管道,在Dart中可以使用File类的create方法来创建文件。创建命名管道的操作类似于创建普通文件,只是我们需要给文件一个特殊的名称,通常以“/tmp/”开头。 在创建完命名管道之后,我们可以使用File类的open方法来打开管道。在Unix示例中,我们需要使用O_RDONLY或者O_WRONLY标识符来指定管道的读写模式。然后,我们可以使用File类的read方法来读取管道中的数据,使用write方法来写入数据。 在进程通信时,通常会有一个进程负责写入数据,另一个进程负责读取数据。这两个进程可以通过访问同一个命名管道实现通信。读取进程会在打开管道之后一直等待数据的到来,直到写入进程管道中写入数据。然后读取进程会读取数据并进行相应的处理。 需要注意的是,在使用命名管道时,需要保证写入和读取的进程顺序是正确的,否则可能会产生读写阻塞的问题。此外,写入和读取的进程使用管道时需要进行同步,以免出现数据竞争的情况。 总结起来,Dart语言可以使用命名管道实现进程通信,类似于Unix中的示例。使用命名管道可以在进程间传递数据,实现数据的读写操作。但是需要注意保证进程的顺序和同步,以确保通信的正确性和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值