赞
踩
在 C# 中,进程间通信(Inter-Process Communication,IPC)进程间通信是指两个或多个程序进程之间的通讯,可以通过多种方式实现:
Socket
MemoryMappedFile
PipeStream
MessageQueue
使用Socket来进行ICP通讯优点如下:
缺点如下:
TcpListener(IPAddress localaddr, int port) 构造一个tcp服务器
Start() 启动一个服务器
BeginAcceptTcpClient 异步等待一个客户连接
// 创建一个 TcpListener 对象,并开始侦听指定的 IP 地址和端口 var listener = new TcpListener(IPAddress.Any, 5000); // 启动服务器 listener.Start(); Console.WriteLine("服务器已启动,正在等待客户端连接..."); // 异步等待服务器连接 tcpListener.BeginAcceptTcpClient(ClientCallBack, tcpListener); // 服务器连接回调 private void ClientCallBack(IAsyncResult ar) { // 获取绑定的对象 TcpListener listener = (TcpListener)ar.AsyncState; // 结束连接等待,获取客户端实例 TcpClient tcpClient = listener.EndAcceptTcpClient(ar); // 获取网络流对象 NetworkStream stream = tcpClient.GetStream(); // 异步发送数据 byte[] data = Encoding.ASCII.GetBytes("hello from service."); stream.BeginWrite(data, 0, data.Length, SendCallBack, tcpClient); // 异步等待客户端消息 stream.BeginRead(data, 0, data.Length, ReceiveCallBack, tcpClient); }
// 创建客户端实例 var client = new TcpClient(); // 连接到服务器 client.Connect(IPAddress.Parse("127.0.0.1"), 5000); Console.WriteLine("Connected to server."); // 获取网络流 var stream = client.GetStream(); // 向服务器发送数据 var data = Encoding.ASCII.GetBytes("Hello from client."); stream.Write(data, 0, data.Length); // 异步等待服务器消息 stream.BeginRead(data, 0, data.Length, ReceiveCallBack, client); // 接收消息回调 private void ReceiveCallBack(IAsyncResult ar) { // 获取绑定的对象 var client = (TcpClient)ar.AsyncState; // 结束读取,获取读到消息的长度 var dataLen = client.EndRead(ar); // 读取到的数据 byte[] temp = new byte[dataLen]; // 从 buffer 读取获取到的数据 复制到 temp Array.Copy(this.Buffer, 0, temp, 0, dataLen); // 异步发送数据 var data = Encoding.ASCII.GetString(temp); Console.WriteLine("Receive data: "+data); }
使用系统的共享内存来进行通讯,
优点:代码简单,速度快
缺点:不适用于跨机器通信, 内存是有限制的是不能满足大量数据通信,多进程数据同步问题
using System; using System.IO; using System.IO.MemoryMappedFiles; namespace SharedMemory { class Program { static void Main(string[] args) { // 在当前进程中创建一个名为 "MyMemory" 的共享内存区域,大小为 1024 字节 using (var memoryMappedFile = MemoryMappedFile.CreateOrOpen("MyMemory", 1024)) { // 使用 MemoryMappedViewAccessor 类来创建一个视图,可以通过它来读写共享内存区域 using (var accessor = memoryMappedFile.CreateViewAccessor()) { // 将整数 123 写入共享内存区域的偏移量为 0 的位置 accessor.Write(0, 123); } } // 在另一个进程中打开名为 "MyMemory" 的共享内存区域 using (var memoryMappedFile = MemoryMappedFile.OpenExisting("MyMemory")) { // 使用 MemoryMappedViewAccessor 类来创建一个视图,可以通过它来读写共享内存区域 using (var accessor = memoryMappedFile.CreateViewAccessor()) { // 从共享内存区域的偏移量为 0 的位置读取一个整数 int value = accessor.ReadInt32(0); Console.WriteLine(value); // 输出 123 } } } } }
管道是一种在两个进程之间进行通信的方式,它们可以在进程之间创建一个通信管道,这样就可以在进程之间发送和接收数据,管道建立连接后,一旦选择阻塞管道接收数据,就不能在调用发送消息方法了,也就是说,一次连接的管道只能用来发消息或接收消息,不能在一个管道上同时发和接收数据,如果需要同时发送或接收数据,请考虑使用Socket通讯
优点有:
缺点有:
NamedPipeServerStream 服务器通信实例
NamedPipeClientStream 客户端通信实例
共有方法:
Write 同步写入数据-此方法会和Read方法互斥,就是不能在一个线程里同时读和写
Read 同步读取数据-此方法会和Write方法互斥,就是不能在一个线程里同时读和写
BeginWrite 异步写入数据方法
BeginRead 异步读取数据方法
写入数据示例:
// 同步写入数据 public void WriteData(byte[] data) { Console.WriteLine("发送数据"); Client.Write(data, 0, data.Length); Client.Flush(); Client.WaitForPipeDrain(); Console.WriteLine("发送完成"); } // 异步写入数据 Client.BeginWrite(data, 0, data.Length, new AsyncCallback(SendCallback), Client); private void SendCallback(IAsyncResult arg) { try { // Get the pipe NamedPipeClientStream var client = arg.AsyncState as NamedPipeClientStream; // End the write pipeStream.EndWrite(iar); client.Flush(); // notify receive client.WaitForPipeDrain(); } catch (Exception) { } }
读取数据示例:
// 同步接收数据 byte[] buffer = new byte[1024]; int bytesRead = 0; do { bytesRead = Client.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { string receivedData = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead); Console.WriteLine("Received data: " + receivedData); bytesRead = 0; } } while (bytesRead == 0); // 异步接收数据 client.BeginRead(this.Buffer, 0, this.Buffer.Length, new AsyncCallback(ReadCallback), client); private void ReadCallback(IAsyncResult arg) { try { var client = arg.AsyncState as NamedPipeClientStream; int length = client.EndRead(arg); if (length > 0) { byte[] temp = new byte[length]; // 从 buffer 读取获取到的数据 复制到 temp Array.Copy(this.Buffer, 0, temp, 0, length); string receivedData = System.Text.Encoding.UTF8.GetString(temp, 0, bytesRead); Console.WriteLine("Received data: " + receivedData); } //再次执行异步读取操作 OnReceiveData(client); } catch (Exception) { } }
消息队列是一种用于在进程、应用程序或主机之间进行消息传递的方法。使用消息队列,可以将消息发送到队列中,然后由接收器从队列中读取消息。这种方式使得发送和接收进程可以独立地运行,并且还可以保证消息按照先进先出(FIFO)的顺序进行处理。
using System; using System.Messaging; namespace MessageQueueExample { class Program { static void Main(string[] args) { // 连接到本地消息队列 string queueName = ".\\private$\\myqueue"; MessageQueue queue = null; if (MessageQueue.Exists(queueName)) { queue = new MessageQueue(queueName); } else { queue = MessageQueue.Create(queueName); } // 发送消息到队列中 string messageBody = "Hello, World!"; Message message = new Message(messageBody); queue.Send(message); // 从队列中接收消息 Message receivedMessage = queue.Receive(); string receivedMessageBody = receivedMessage.Body.ToString(); Console.WriteLine("Received message: " + receivedMessageBody); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。