windows编程学习——命名通道

命名管道数据传输过程:在服务器端调用CreateNamedpipe创建命名管道之后,调用ConnectNamedpipe函数让服务器端进程等待客户端进程连接到该命名管道的实例上。
在客户端首先调用WaiteNamedpipe函数判断当前是否有可以利用的命名管道实例,如果有,就调用CreateFile函数打开该命名管道的实例,并且建立一个连接。

下面是一些函数,以及一个具体实例

服务器端程序:

#include <stdio.h>
#include <Windows.h>
#define	PIPENAME0	"//./Pipe/Test"    //管道名
#define	MAXDATANUM	1024


int main()
{
	DWORD		ReadNum = 0;  //DWORD 表示32位字节无符号整数这里定义了服务器读入的字节数ReadNum初始为0   Windows下经常用来保存地址(或者存放指针) 
	char		buffer[MAXDATANUM];//定义一个char类型的数组存放读取的数据
	HANDLE		g_hPipe = INVALID_HANDLE_VALUE;//HANDLE是专门定义句柄的标示符 定义了一个名为g_hPipe的句柄为无效句柄值


	printf("Server of name pipe is testing..........\n");
	//创建名称为Test的命名管道
	g_hPipe = CreateNamedPipe(PIPENAME0,PIPE_ACCESS_DUPLEX,PIPE_READMODE_BYTE,2,0,0,1000,NULL); //g_hPipe表示管道句柄
	// 参数1 PIPENAME0 表示管道的名称   参数2 PIPE_ACCESS_DUPLEX 表示管道创建好后的打开模式即标志以双向传输方式打开一个管道(双工通信)
	//参数3 PIPE_READMODE_BYTE 命名管道提供以字节方式通信 参数4 “2”表示管道内的最大实例数 参数“0”,“0”,“1000”,“NULL”分别表示输出缓存大小、输入缓存大小、超时设置、安全属性的指针 
	if (INVALID_HANDLE_VALUE == g_hPipe)
	{
		printf("Create name pipe is failed......\n");
		CloseHandle(g_hPipe);
		getchar();
		return 0;
	}//判断句柄是否有效如果无效调用CloseHandle函数关闭句柄
	printf("Waiting connect......\n");
	if (FALSE == ConnectNamedPipe(g_hPipe,NULL))
	{
		printf("Connect is failed......\n");
		CloseHandle(g_hPipe);
		getchar();
		return 0;
	}//判断客户端与管道是否连接若未连接则关闭管道
	printf("Connect is successful......\n");
	printf("Read data is starting......\n");//连接成功输出......
	while(1)
	{
		memset(buffer,0,MAXDATANUM);//将buffer数组中所有字符清零
		if (!(ReadFile(g_hPipe,&buffer,sizeof(buffer),&ReadNum,NULL)))//判断读取操作是否成功  ReadFile作用:从文件指针指向的位置开始将数据读出到一个文件中
		{
			printf("Read data is closing......\n");
			CloseHandle(g_hPipe);          //关闭管道句柄
			getchar();
			return 0;


		}
		printf("Receive data is %s\n",buffer);  //打印出接收的数据
		Sleep(100);//执行挂起操作
	}


	CloseHandle(g_hPipe);//数据传输完成后关闭管道
	getchar();
	return 0;
}
	PIPENAME0	"//./Pipe/Test"    //管道名
#define	MAXDATANUM	1024


int main()
{
	DWORD		ReadNum = 0;  //DWORD 表示32位字节无符号整数这里定义了服务器读入的字节数ReadNum初始为0   Windows下经常用来保存地址(或者存放指针) 
	char		buffer[MAXDATANUM];//定义一个char类型的数组存放读取的数据
	HANDLE		g_hPipe = INVALID_HANDLE_VALUE;//HANDLE是专门定义句柄的标示符 定义了一个名为g_hPipe的句柄为无效句柄值


	printf("Server of name pipe is testing..........\n");
	//创建名称为Test的命名管道
	g_hPipe = CreateNamedPipe(PIPENAME0,PIPE_ACCESS_DUPLEX,PIPE_READMODE_BYTE,2,0,0,1000,NULL); //g_hPipe表示管道句柄
	// 参数1 PIPENAME0 表示管道的名称   参数2 PIPE_ACCESS_DUPLEX 表示管道创建好后的打开模式即标志以双向传输方式打开一个管道(双工通信)
	//参数3 PIPE_READMODE_BYTE 命名管道提供以字节方式通信 参数4 “2”表示管道内的最大实例数 参数“0”,“0”,“1000”,“NULL”分别表示输出缓存大小、输入缓存大小、超时设置、安全属性的指针 
	if (INVALID_HANDLE_VALUE == g_hPipe)
	{
		printf("Create name pipe is failed......\n");
		CloseHandle(g_hPipe);
		getchar();
		return 0;
	}//判断句柄是否有效如果无效调用CloseHandle函数关闭句柄
	printf("Waiting connect......\n");
	if (FALSE == ConnectNamedPipe(g_hPipe,NULL))
	{
		printf("Connect is failed......\n");
		CloseHandle(g_hPipe);
		getchar();
		return 0;
	}//判断客户端与管道是否连接若未连接则关闭管道
	printf("Connect is successful......\n");
	printf("Read data is starting......\n");//连接成功输出......
	while(1)
	{
		memset(buffer,0,MAXDATANUM);//将buffer数组中所有字符清零
		if (!(ReadFile(g_hPipe,&buffer,sizeof(buffer),&ReadNum,NULL)))//判断读取操作是否成功  ReadFile作用:从文件指针指向的位置开始将数据读出到一个文件中
		{
			printf("Read data is closing......\n");
			CloseHandle(g_hPipe);          //关闭管道句柄
			getchar();
			return 0;


		}
		printf("Receive data is %s\n",buffer);  //打印出接收的数据
		Sleep(100);//执行挂起操作
	}


	CloseHandle(g_hPipe);//数据传输完成后关闭管道
	getchar();
	return 0;
}

服务器端:

 

(1)创建命名管道函数CreateNamedPipe
原型  HANDLE CreateNamedPipe(
  LPCTSTR lpName, // 指向管道名称的指针
  DWORD dwOpenMode, // 管道打开模式
  DWORD dwPipeMode, // 管道模式
  DWORD nMaxInstances, // 最大实例数
  DWORD nOutBufferSize, // 输出缓存大小
  DWORD nInBufferSize, // 输入缓存大小
  DWORD nDefaultTimeOut, // 超时设置
  LPSECURITY_ATTRIBUTES lpSecurityAttributes // 安全属性指针
);


     (2) 在命名管道实例上监听客户机连接请求的函数ConnectNamedPipe
原型:ConnectNamedPipe(
            HANDLE hNamedPipe,
            LPOVERLAPPED lpOverlapped
    );
参数含义:
         hNamedPipe:管道的句柄
         lpOverlapped ,如果设为NULL(传递ByVal As Long),表示将线程挂起,直到一个客户端同管道连接为止。
否则就立即返回;此时,如果管道尚未连接,客户同管道连接时就会触发lpOverlapped结构中的事件对象。随后,可用一个等待函数来监视连接


      (3)从客户机接收数据函数ReadFile:         
原型:BOOL ReadFile(
HANDLE hFile, //文件的句柄
LPVOID lpBuffer, //用于保存读入数据的一个缓冲区
DWORD nNumberOfBytesToRead, //要读入的字节数
LPDWORD lpNumberOfBytesRead,//指向实际读取字节数的指针
LPOVERLAPPED lpOverlapped //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须用这个参数引用一个特殊的结构。该结构定义了一次异步读取操作。否则,应将这个参数设为NULL
 );


      (4)关闭命名管道实例句柄函数CloseHandle:
CloseHandle(
    __in HANDLE hObject   //代表一个已打开对象句柄
    ); 
     (5)memset函数
  void *memset(void *s, int ch, size_t n);函数解释:将s中前n个字节替换为ch并返回s
  memset功能:是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。

 

客户端:

#include <stdio.h>
#include <Windows.h>

#define	PIPENAME0	"//./Pipe/Test"    //管道名
#define	MAXDATANUM	1024

int main()
{
	DWORD		ReadNum = 0;  //DWORD 表示32位字节无符号整数这里定义了服务器读入的字节数ReadNum初始为0   Windows下经常用来保存地址(或者存放指针) 
	char		buffer[MAXDATANUM];//定义一个char类型的数组存放读取的数据
	HANDLE		g_hPipe = INVALID_HANDLE_VALUE;//HANDLE是专门定义句柄的标示符 定义了一个名为g_hPipe的句柄为无效句柄值

	printf("Server of name pipe is testing..........\n");
	//创建名称为Test的命名管道
	g_hPipe = CreateNamedPipe(PIPENAME0,PIPE_ACCESS_DUPLEX,PIPE_READMODE_BYTE,2,0,0,1000,NULL); //g_hPipe表示管道句柄
	// 参数1 PIPENAME0 表示管道的名称   参数2 PIPE_ACCESS_DUPLEX 表示管道创建好后的打开模式即标志以双向传输方式打开一个管道(双工通信)
	//参数3 PIPE_READMODE_BYTE 命名管道提供以字节方式通信 参数4 “2”表示管道内的最大实例数 参数“0”,“0”,“1000”,“NULL”分别表示输出缓存大小、输入缓存大小、超时设置、安全属性的指针 
	if (INVALID_HANDLE_VALUE == g_hPipe)
	{
		printf("Create name pipe is failed......\n");
		CloseHandle(g_hPipe);
		getchar();
		return 0;
	}//判断句柄是否有效如果无效调用CloseHandle函数关闭句柄
	printf("Waiting connect......\n");
	if (FALSE == ConnectNamedPipe(g_hPipe,NULL))
	{
		printf("Connect is failed......\n");
		CloseHandle(g_hPipe);
		getchar();
		return 0;
	}//判断客户端与管道是否连接若未连接则关闭管道
	printf("Connect is successful......\n");
	printf("Read data is starting......\n");//连接成功输出......
	while(1)
	{
		memset(buffer,0,MAXDATANUM);//将buffer数组中所有字符清零
		if (!(ReadFile(g_hPipe,&buffer,sizeof(buffer),&ReadNum,NULL)))//判断读取操作是否成功  ReadFile作用:从文件指针指向的位置开始将数据读出到一个文件中
		{
			printf("Read data is closing......\n");
			CloseHandle(g_hPipe);          //关闭管道句柄
			getchar();
			return 0;

		}
		printf("Receive data is %s\n",buffer);  //打印出接收的数据
		Sleep(100);//执行挂起操作
	}

	CloseHandle(g_hPipe);//数据传输完成后关闭管道
	getchar();
	return 0;
}

1)呼叫对服务器的连接函数CreateFile:
原型:HANDLE WINAPI CreateFile(
_In_ LPCTSTR lpFileName,//要打开的文件的名字
_In_ DWORD dwDesiredAccess,//设备访问方式比如:GENERIC_READ或者是GENERIC_WRITE
_In_ DWORD dwShareMode,//共享方式  表示只能接受一个客户端的请求的到来 不需要共享
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,//安全特性NULL
_In_ DWORD dwCreationDisposition,//设置文件操作的要求     在打开一个通信端口时如管道,无论如何都要设置成 OPEN_EXISTING打开现有的管道
_In_ DWORD dwFlagsAndAttributes,//文档属性 FELE_ATTRIBUTE_NORMAL
_In_opt_ HANDLE hTemplateFile  //模板文件 如果不为零,则指定一个文件句柄。新文件将从这个文件中复制扩展属性


);
函数功能:这是一个多功能的函数,可打开或创建以下对象,并返回可访问的句柄
参数类型及说明
lpFileName String,要打开的文件的名字
dwDesiredAccessLong,如果为 GENERIC_READ 表示允许对设备进行读访问;如果为 GENERIC_WRITE 表示允许对设备进行写访问(可组合使用);如果为零,表示只允许获取与一个设备有关的信息
dwShareMode Long,零表示不共享; FILE_SHARE_READ 和/或 FILE_SHARE_WRITE 表示允许对文件进行共享访问
lpSecurityAttributes SECURITY_ATTRIBUTES,指向一个SECURITY_ATTRIBUTES结构的指针,定义了文件的安全特性
dwCreationDisposition Long,下述常数之一:
CREATE_NEW 创建文件;如文件存在则会出错
CREATE_ALWAYS 创建文件,会改写前一个文件
OPEN_EXISTING 文件必须已经存在。由设备提出要求
OPEN_ALWAYS 如文件不存在则创建它
TRUNCATE_EXISTING 将现有文件缩短为零长度
dwFlagsAndAttributesLong,一个或多个下述常数
FILE_ATTRIBUTE_ARCHIVE 标记归档属性
FILE_ATTRIBUTE_COMPRESSED 将文件标记为已压缩,或者标记为文件在目录中的默认压缩方式
FILE_ATTRIBUTE_NORMAL 默认属性
FILE_ATTRIBUTE_HIDDEN 隐藏文件或目录
FILE_ATTRIBUTE_READONLY 文件为只读
FILE_ATTRIBUTE_SYSTEM 文件为系统文件
FILE_FLAG_WRITE_THROUGH操作系统不得推迟对文件的写操作
FILE_FLAG_OVERLAPPED 允许对文件进行重叠操作
FILE_FLAG_NO_BUFFERING 禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块
FILE_FLAG_RANDOM_ACCESS 针对随机访问对文件缓冲进行优化
FILE_FLAG_SEQUENTIAL_SCAN针对连续访问对文件缓冲进行优化
FILE_FLAG_DELETE_ON_CLOSE 关闭了上一次打开的句柄后,将文件删除。特别适合临时文件

也可在Windows NT下组合使用下述常数标记:
SECURITY_ANONYMOUS, SECURITY_IDENTIFICATION, SECURITY_IMPERSONATION, SECURITY_DELEGATION, SECURITY_CONTEXT_TRACKING, SECURITY_EFFECTIVE_ONLY
hTemplateFile Long,相当于一个模板,如果不为零,则指定一个文件句柄。新文件将从这个文件中复制扩展属性即相当于拷贝的功能

(2)WriteFile将数据发给客户机
BOOL WriteFile(
HANDLE hFile, // 文件句柄
LPCVOID lpBuffer,// 数据缓存区指针
DWORD nNumberOfBytesToWrite,// 你要写的字节数
LPDWORD lpNumberOfBytesWritten, // 用于保存实际写入字节数的存储区域的指针
LPOVERLAPPED lpOverlapped // OVERLAPPED结构体指针   如果文件是以FILE_FLAG_OVERLAPPED方式打开的话,那么这个指针就不能为NULL
);

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值