欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C# C++ 使用命名管道进行进程通信

程序员文章站 2022-03-26 21:42:06
实现的功能:C#和C++的应用程序运行时,这两个进程间可以进行进程通信,互相发送和接收消息。之前看了很多网上的代码写进程通信,大多数都是讲C#——C#或C++——C++这种相同类型的应用程序间的通信,很少有C#->C++或C++->C#这种不同类型的应用程序间的通信。但仔细想想,系统中的进程通过创建、连接管道(Pipe)完成进程通信,那么这个创建、连接的过程,张三有张三的创建方法,......

实现的功能:C#和C++的应用程序运行时,这两个进程间可以进行进程通信,互相发送和接收消息。

之前看了很多网上的代码写进程通信,大多数都是讲C#——C#或C++——C++这种相同类型的应用程序间的通信,很少有C#->C++或C++->C#这种不同类型的应用程序间的通信。但仔细想想,系统中的进程通过创建、连接管道(Pipe)完成进程通信,那么这个创建、连接的过程,张三有张三的创建方法,李四有李四的连接方法,但这有什么关系呢,它们最终达到的结果一致就可以了。因此,在实现C#和C++之间的进程通信时,我们只需要用它们各自自己的方法来创建管道、连接管道,例如,我们以C#端为服务器端,以C++端为客户端,C#通过NamePipeServerStream创建管道,C++通过WaitNamedPipe和CreateFile等待连接管道就能实现C#和C++进程间的进程通信。以下我们来详细讲诉。

 

首先,你必须要先了解C#和C++各自的管道通信机制,无论是作为客户端还是服务器,这样无论是哪种需求你都可以将其两两组合,达到你想要的效果。

C#:

服务器(NamePipeServerStream):https://docs.microsoft.com/zh-cn/dotnet/api/system.io.pipes.namedpipeserverstream?view=netframework-4.7.2

客户端(NamePipeClientStream):https://docs.microsoft.com/zh-cn/dotnet/api/system.io.pipes.namedpipeclientstream?view=netframework-4.7.2

C++:

可参见博客 :https://blog.csdn.net/u010797208/article/details/41566395 

 

接下来,我们便可根据自己的目标需求将它们组合起来,示例以C#为服务器,以C++为客户端实现两者之间的通信,如下。

C# 服务器端:

        NamedPipeServerStream m_pipe_server = null;
        StreamWriter sw = null;
        StreamReader sr = null;
        /*点击按钮创建连接并发送消息*/
        protected void onSendButtonClick(object sender, RoutedEventArgs e)
        {
            if (m_pipe_server == null)
            {
                m_pipe_server = new NamedPipeServerStream("mypipe");
                m_pipe_server.WaitForConnection();
            }
            if (sw == null) { sw = new StreamWriter(m_pipe_server); sw.AutoFlush = true; }
            if (sr == null) sr = new StreamReader(m_pipe_server);

            sw.WriteLine("I am server.");
            string srstr = sr.ReadLine();
            this.TextBox1.Text = "hi:" + srstr;
        }

C++ 客户端:

        bool is_pipe_setup = false;
	HANDLE pipe_client = nullptr;

        /*客户端一直在等待服务器发起连接,管道创建成功后发送消息*/
	while (1)
	{
		if(is_pipe_setup == false)
		{
			BOOL ret = WaitNamedPipe(TEXT("\\\\.\\Pipe\\mypipe"), NMPWAIT_WAIT_FOREVER);
			if (ret)
			{
				pipe_client = CreateFile(
					TEXT("\\\\.\\Pipe\\mypipe"),
					GENERIC_WRITE | GENERIC_READ,
					0,
					NULL,
					OPEN_EXISTING,
					FILE_ATTRIBUTE_NORMAL,
					NULL
				);

				if (pipe_client == INVALID_HANDLE_VALUE) continue;
				else is_pipe_setup = true;
			}
		}

		char readbuf[256] = "";
		char writebuf[256] = "I am client, I am writing \n";
		DWORD readlen = 0;
		DWORD writelen = 0;
		if (ReadFile(pipe_client, readbuf, sizeof(readbuf), &readlen, NULL) != FALSE)
		cout << readbuf << endl;

		if (WriteFile(pipe_client, writebuf, sizeof(writebuf), &writelen, NULL) != FALSE)
		{
			cout << "client write success" << endl;
		}

两边的各个方面都要完全匹配对于。例如创建和等待连接的管道名称应该相同;一方发送数据另一方则接收数据等等。尤其要注意的一点是,当接收数据的一方使用Readline()函数读取管道数据时,发送方一定要注意发送的信息最后必须带有“\n”换行符!否则,接收方会一直认定接受数据尚未结束,一直处于等待接收状态,程序则无法继续运行下去!我写的时候被这个坑卡了很久。。。。

 

转载请注明出处!

谢谢~

本文地址:https://blog.csdn.net/SimonSmile/article/details/85273894