在.Net开发中,通常可以使用以下几种方式实现多进程之间的通信:
1. 内存映射文件(Memory-mapped Files):内存映射文件允许不同进程共享同一段物理内存。当一个进程将数据写入内存映射文件时,其他进程可以通过读取该内存映射文件来访问这些数据。
- // 创建内存映射文件
- using var mmf = MemoryMappedFile.CreateNew("TestMap", 10000);
- // 获取内存映射文件中的视图
- using var view = mmf.CreateViewAccessor();
- // 向内存映射文件写入数据
- byte[] buffer = ...
- view.WriteArray(0, buffer, 0, buffer.Length);
- // 从内存映射文件中读取数据
- byte[] readBuffer = new byte[buffer.Length];
- view.ReadArray(0, readBuffer, 0, readBuffer.Length);
2. 命名管道(Named Pipes):命名管道是一种单向或双向通信机制,可以在多个进程间进行通信。一个进程将数据写入其中一个命名管道,而另一个进程则从该管道中读取数据。
- // 创建服务器端命名管道
- var pipeServer = new NamedPipeServerStream("TestPipe");
- // 等待客户端连接
- pipeServer.WaitForConnection();
- // 向管道中写入消息
- byte[] buffer = ...
- pipeServer.Write(buffer, 0, buffer.Length);
- // 关闭管道
- pipeServer.Close();
- // 创建客户端命名管道
- var pipeClient = new NamedPipeClientStream("TestPipe");
- // 连接服务器端管道
- pipeClient.Connect();
- // 从管道中读取消息
- byte[] readBuffer = new byte[buffer.Length];
- pipeClient.Read(readBuffer, 0, readBuffer.Length);
- // 关闭管道
- pipeClient.Close();
3. 远程过程调用(Remote Procedure Call, RPC):远程过程调用是一种通过网络通信实现进程间通信的方法。它允许一个进程调用另一个进程(通常是运行在远程计算机上)中的函数,并返回结果。
- // 创建RPC服务主机
- var host = new ServiceHost(typeof(MyService));
- host.Open();
- // 创建RPC客户端代理(需要引用服务契约)
- var client = new MyServiceClient();
- // 调用远程方法
- var result = client.MyMethod("参数");
- // 关闭RPC客户端代理
- client.Close();
- // 关闭RPC服务主机
- host.Close();
4. Windows消息队列:Windows消息队列是一种通过操作系统提供的通信机制实现进程间通信的方式。它基于Windows消息机制,可用于在多个进程之间传递消息。
- // 创建消息队列
- var queue = MessageQueue.Create(@".\Private$\MyQueue");
- // 发送消息
- var message = new Message
- {
- Body = "消息内容"
- };
- queue.Send(message);
- // 接收消息
- var message = queue.Receive();
- string body = (string)message.Body;
- // 删除消息
- queue.ReceiveById(message.Id);
- // 删除消息队列
- MessageQueue.Delete(@".\Private$\MyQueue");
5. .NET Remoting:.NET Remoting 是一种在相互协作的对象之间提供远程对象调用服务的机制,可以用于在多个进程之间进行通信。
- // 创建远程对象
- var obj = new MyRemoteObject();
- // 启动远程对象服务
- var channel = new TcpChannel(12345);
- ChannelServices.RegisterChannel(channel, false);
- RemotingServices.Marshal(obj, "MyRemoteObject");
- // 创建远程对象代理
- var proxy = (MyRemoteObject)Activator.GetObject(
- typeof(MyRemoteObject), "tcp://localhost:12345/MyRemoteObject");
- // 调用远程方法
- var result = proxy.MyMethod("参数");
- // 关闭远程对象代理
- RemotingServices.Disconnect(proxy);
- // 停止远程对象服务
- ChannelServices.UnregisterChannel(channel);
6. Socket:使用TCP或UDP协议进行通信,需要处理网络编程相关问题。
- // 服务器端
- var listener = new TcpListener(IPAddress.Loopback, 12345);
- listener.Start();
- while (true)
- {
- var client = listener.AcceptTcpClient();
- using var networkStream = client.GetStream();
- // 处理网络流中的数据
- }
- // 客户端
- var client = new TcpClient();
- client.Connect(IPAddress.Loopback, 12345);
- using var networkStream = client.GetStream();
- // 向服务端发送数据
- byte[] buffer = ...
- networkStream.Write(buffer, 0, buffer.Length);
- // 从服务端接收数据
- byte[] readBuffer = new byte[buffer.Length];
- networkStream.Read(readBuffer, 0, readBuffer.Length);
- client.Close();
7. PipeStream:使用命名管道或匿名管道进行通信,与Named Pipes类似。
- // 服务器端
- var serverPipe = new NamedPipeServerStream("MyPipe", PipeDirection.InOut);
- serverPipe.WaitForConnection();
- // 读取客户端发来的消息
- using var streamReader = new StreamReader(serverPipe);
- var message = streamReader.ReadToEnd();
- // 发送响应消息到客户端
- using var streamWriter = new StreamWriter(serverPipe);
- streamWriter.WriteLine("响应消息");
- streamWriter.Flush();
- // 客户端
- var clientPipe = new NamedPipeClientStream(".", "MyPipe", PipeDirection.InOut);
- clientPipe.Connect();
- // 向服务器发送消息
- using var streamWriter = new StreamWriter(clientPipe);
- streamWriter.WriteLine("请求消息");
- streamWriter.Flush();
- // 读取服务器返回的响应消息
- using var streamReader = new StreamReader(clientPipe);
- var response = streamReader.ReadLine();
8. Shared Memory:使用共享内存进行通信,与Memory-mapped Files类似。
- // 创建MemoryMappedFile
- var memoryMappedFile = MemoryMappedFile.CreateNew(
- "MySharedMemory", 4096, MemoryMappedFileAccess.ReadWrite);
- // 获取共享内存视图
- var memoryMappedViewAccessor = memoryMappedFile.CreateViewAccessor();
- // 在共享内存中写入数据
- byte[] buffer = ...
- memoryMappedViewAccessor.WriteArray(0, buffer, 0, buffer.Length);
- // 读取共享内存中的数据
- byte[] readBuffer = new byte[buffer.Length];
- memoryMappedViewAccessor.ReadArray(0, readBuffer, 0, readBuffer.Length);
9. MSMQ(Microsoft Message Queue):使用消息队列进行通信,相较于Windows消息队列更加高级,支持分布式事务和异步发送等特性。
- // 创建消息队列
- var messageQueue = new MessageQueue(@".\Private$\MyQueue")
- {
- Formatter = new XmlMessageFormatter(new[] { typeof(string) })
- };
- // 发送消息
- messageQueue.Send("请求消息");
- // 接收消息
- var message = messageQueue.Receive();
- string body = (string)message.Body;
- // 删除消息
- messageQueue.ReceiveById(message.Id);
- // 删除消息队列
- MessageQueue.Delete(@".\Private$\MyQueue");
10. MQTT(Message Queuing Telemetry Transport):一种轻量级的、基于发布/订阅模型的消息协议,通常用于物联网和移动应用场景。
- // 创建MQTT客户端
- var client = new MqttClient(IPAddress.Loopback);
- // 连接MQTT服务器
- client.Connect("MyClient");
- // 订阅主题并接收消息
- client.Subscribe(new[] { "topic/mytopic" }, new[] { MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE });
- client.MqttMsgPublishReceived += (s, e) =>
- {
- var message = Encoding.UTF8.GetString(e.Message);
- };
- // 发布消息
- var payload = Encoding.UTF8.GetBytes("消息内容");
- client.Publish("topic/mytopic", payload);
以上就是.Net开发中常用的多进程通信方式,每种方式都有其适用场景和注意事项。需要根据具体需求进行选择和设计。
原文地址:https://www.toutiao.com/article/7228984003972694584/