zoukankan      html  css  js  c++  java
  • 进程间通讯(二)--管道

    管道分为命名管道和匿名管道,首先我们谈一下命名管道。

    一。命名管道(Named Pipe)

    命名管道双向,跨网络,任何进程都可以轻易的抓住,放进管道的数据有固定的格 式,而使用ReadFile()只能读取该大小的倍数。

    其实管道的使用方法与文件类似,都能使用read,write,open等普通IO函数. 管道描述符来类似于文件描述符. 事实上, 管道使用的描述符,文件指针和文件描述符最终都会转化成系统中SOCKET描述符.,都受到系统内核中SOCKET描述符的限制.。本质上LINUX内核源码中管道是通过空文件来实现。


    Server端:

    #include "stdafx.h"
    #include <Windows.h>
    #include <iostream>
    using namespace std;
    
    #define NAMED_PIPE   L"\\.\PIPE\NamedPipe"
    #define BUFFER_SIZE 0x1000
    int main()
    {
    	HANDLE PipeHandle = CreateNamedPipe(NAMED_PIPE,  //名称
    		PIPE_ACCESS_DUPLEX,       //打开模式
    		PIPE_TYPE_MESSAGE |       //管道模式
    		PIPE_READMODE_MESSAGE |
    		PIPE_WAIT,
    		PIPE_UNLIMITED_INSTANCES,//实例最大数
    		BUFFER_SIZE,//最大传输数
    		BUFFER_SIZE,//最大传入数
    		0,                   //时间
    		NULL);
    	if (PipeHandle == INVALID_HANDLE_VALUE)
    	{
    		printf("Can't Create Named Pipe!
    ");
    		return 0;
    	}
    
    	BOOL bOk = ConnectNamedPipe(PipeHandle, NULL);
    	if (bOk == FALSE)
    	{
    		printf("Can't Connect Named Pipe!
    ");
    		CloseHandle(PipeHandle);
    		return 0;
    	}
    	char BufferData[BUFFER_SIZE] = { 0 };
    	DWORD BufferLegth = 0;
    	while (true)
    	{
    		bOk = ReadFile(PipeHandle, BufferData, sizeof(BufferData), &BufferLegth, NULL);
    		printf("%s
    ", BufferData);
    		if (!strcmp(BufferData,"Bye"))
    		{
    			break;
    		}	
    		printf("Please Input The Word!
    ");
    		cin >> BufferData;
    		bOk = WriteFile(PipeHandle, BufferData, strlen(BufferData), &BufferLegth, NULL);
    	}
    	
    	CloseHandle(PipeHandle);
        return 0;
    }

    Client端:

    #include "stdafx.h"
    #include <Windows.h>
    #include <iostream>
    using namespace std;
    
    #define NAMED_PIPE   L"\\.\PIPE\NamedPipe"
    #define BUFFER_SIZE 0x1000
    int main()
    {
    	char BufferData[BUFFER_SIZE] = { 0 };  //传送过去的数据
    	DWORD BufferLegth = 0;
    	char szOutBufferData[BUFFER_SIZE] = { 0 };              //传送过来的数据
    	while (true)
    	{
    		printf("Please Input The Word!
    ");
    		ZeroMemory(BufferData, BUFFER_SIZE);
    		cin >> BufferData;
    		if (CallNamedPipe(NAMED_PIPE, BufferData, sizeof(BufferData), szOutBufferData, BUFFER_SIZE, &BufferLegth, NMPWAIT_WAIT_FOREVER) != 0)  //WriteFile ReadFile CloseHandle
    		{
    			printf("%s
    ", szOutBufferData);
    		}
    		if (!strcmp(BufferData,"Bye"))
    		{
    			break;
    		}
    	}
        return 0;
    }
    

    二.匿名管道(Anonymous Pipes)

    匿名管道与命名管道有些不同,使用限制也较多,主要在以下两方面:
    第一:匿名管道只能实现本地进程之间的通信,不能实现跨网络之间的进程间的通信。
    第二:匿名管道只能实现父进程和子进程之间的通信,而不能实现任意两个本地进程之间的通信。
    实例:
    Server端:
    #include "stdafx.h"
    #include <Windows.h>
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	//初始化
    	SECURITY_ATTRIBUTES SecurityAttributes;
    	SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
    	SecurityAttributes.bInheritHandle = TRUE;
    	SecurityAttributes.lpSecurityDescriptor = NULL;
    
    	HANDLE ReadHandle = NULL;
    	HANDLE WriteHandle = NULL;
    
    	if (!CreatePipe(&ReadHandle, &WriteHandle, &SecurityAttributes, 0))
    	{
    		printf("Can't Create pipe
    ");
    		return 0;
    	}
    	
    	//创建子进程
    	STARTUPINFO StartupInfo;
    	PROCESS_INFORMATION ProcessInfo;
    	ZeroMemory(&StartupInfo, sizeof(STARTUPINFO));
    	StartupInfo.cb = sizeof(STARTUPINFO);
    	StartupInfo.dwFlags = STARTF_USESTDHANDLES;
    	StartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
    	StartupInfo.hStdInput = ReadHandle;
    	StartupInfo.hStdOutput = WriteHandle;
    
    	if (!CreateProcess(L"NoNamedPipeClient.exe", NULL, NULL, NULL, TRUE, 0,NULL,NULL, &StartupInfo, &ProcessInfo))
    	{
    		int e = GetLastError();
    		CloseHandle(ReadHandle);
    		CloseHandle(WriteHandle);
    		return 0;
    	}
    	else
    	{
    		CloseHandle(ProcessInfo.hProcess);
    		CloseHandle(ProcessInfo.hThread);
    	}
    
    	while (true)
    	{
    		char  BufferData[0x100] = { 0 };
    		DWORD BufferLength = 0;
    		ZeroMemory(BufferData, sizeof(BufferData));
    		if (ReadFile(ReadHandle,BufferData,sizeof(BufferData),&BufferLength,NULL))
    		{
    			if (!strcmp(BufferData, "Bye"))
    			{
    				break;
    			}
    			printf("Client:%s 
    ",BufferData);
    		}
    		printf("Please Input The Word!
    ");
    		ZeroMemory(BufferData, sizeof(BufferData));
    		cin >> BufferData;
    		if (!strcmp(BufferData, "Bye"))
    		{
    			break;
    		}
    		if (WriteFile(WriteHandle, BufferData, sizeof(BufferData), &BufferLength, NULL))
    		{
    			
    		}
    
    	}
    
    	CloseHandle(ReadHandle);
    	CloseHandle(WriteHandle);
        return 0;
    }
    
    Client端:
    #include "stdafx.h"
    #include <Windows.h>
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	HANDLE ReadHandle = NULL;
    	HANDLE WriteHandle = NULL;
    	ReadHandle = GetStdHandle(STD_INPUT_HANDLE);
    	WriteHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    
    	if (ReadHandle==INVALID_HANDLE_VALUE||WriteHandle==INVALID_HANDLE_VALUE)
    	{
    		printf("Can't Get Handle;
    ");
    
    		return 0;
    	}
    	while (true)
    	{
    		char  BufferData[0x100] = { 0 };
    		DWORD BufferLength = 0;
    		ZeroMemory(BufferData, sizeof(BufferData));
    		printf("Please Input The Word!
    ");
    		cin >> BufferData;
    		if (!strcmp(BufferData, "Bye"))
    		{
    			break;
    		}
    		WriteFile(WriteHandle, BufferData, sizeof(BufferData), &BufferLength, NULL);
    		ZeroMemory(BufferData, sizeof(BufferData));
    		if (ReadFile(ReadHandle, BufferData, sizeof(BufferData), &BufferLength, NULL))
    		{
    			if (!strcmp(BufferData, "Bye"))
    			{
    				break;
    			}
    			printf("Client:%s 
    ", BufferData);
    		}
    	}
    	CloseHandle(ReadHandle);
    	CloseHandle(WriteHandle);
        return 0;
    }


  • 相关阅读:
    删DS.Store
    switch 多重选择
    PrintWrite写入文件
    读取文件
    notepad++如何把文件保存为java文件
    让notepad++成为轻量级JAVA的IDE
    Jenkins构建Python项目提示:'python' 不是内部或外部命令,也不是可运行的程序
    相关服务账号
    Jenkins安装与启动
    jmeter安装
  • 原文地址:https://www.cnblogs.com/Toring/p/6628270.html
Copyright © 2011-2022 走看看