C# 两个进程/exe通讯方式 两个应用程序通讯方式
C# 两个exe通讯方式 两个应用程序通讯方式
1. 命名管道(Named Pipes)
1.1. 概述
命名管道是一种用于在同一台机器或网络中不同进程之间进行双向通信的机制。它支持同步和异步通信,适用于需要高效数据传输的场景。
1.2. 特点
双向通信:支持双向数据传输。
安全性:可以设置访问权限,确保通信的安全性。
跨网络:支持跨网络通信。
1.3. 实现方式
1.3.1. 服务器端(NamedPipeServerStream)
using System;
using System.IO.Pipes;
using System.Text;
using System.Threading.Tasks;class PipeServer
{public static async Task StartServer(){using (var pipeServer = new NamedPipeServerStream("TestPipe", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous)){Console.WriteLine("等待客户端连接...");await pipeServer.WaitForConnectionAsync();Console.WriteLine("客户端已连接。");// 接收数据byte[] buffer = new byte[256];int bytesRead = await pipeServer.ReadAsync(buffer, 0, buffer.Length);string receivedMessage = Encoding.UTF8.GetString(buffer, 0, bytesRead);Console.WriteLine($"收到消息:{receivedMessage}");// 发送回应string response = "Hello from server!";byte[] responseBytes = Encoding.UTF8.GetBytes(response);await pipeServer.WriteAsync(responseBytes, 0, responseBytes.Length);Console.WriteLine("已发送回应。");}}static void Main(string[] args){Task.Run(() => StartServer()).Wait();}
}
1.3.2. 客户端(NamedPipeClientStream)
using System;
using System.IO.Pipes;
using System.Text;
using System.Threading.Tasks;class PipeClient
{public static async Task StartClient(){using (var pipeClient = new NamedPipeClientStream(".", "TestPipe", PipeDirection.InOut, PipeOptions.Asynchronous)){Console.WriteLine("尝试连接到服务器...");await pipeClient.ConnectAsync();Console.WriteLine("已连接到服务器。");// 发送数据string message = "Hello from client!";byte[] messageBytes = Encoding.UTF8.GetBytes(message);await pipeClient.WriteAsync(messageBytes, 0, messageBytes.Length);Console.WriteLine("已发送消息。");// 接收回应byte[] buffer = new byte[256];int bytesRead = await pipeClient.ReadAsync(buffer, 0, buffer.Length);string response = Encoding.UTF8.GetString(buffer, 0, bytesRead);Console.WriteLine($"收到回应:{response}");}}static void Main(string[] args){Task.Run(() => StartClient()).Wait();}
}
1.4. 使用场景
需要高效、双向通信的应用程序。
同一台机器或网络中的进程间通信。
需要传输大量数据或复杂数据结构。
2. 套接字(Sockets)
2.1. 概述
套接字是一种底层的通信机制,支持跨网络的进程间通信。它适用于需要跨不同机器或网络通信的应用程序。
2.2. 特点
灵活性高:支持多种协议(TCP、UDP)。
跨平台:可用于不同操作系统间的通信。
高性能:适用于实时数据传输和高并发应用。
2.3. 实现方式
2.3.1. 服务器端(TCP)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class SocketServer
{public static async Task StartServer(){TcpListener listener = new TcpListener(IPAddress.Any, 5000);listener.Start();Console.WriteLine("服务器已启动,等待连接...");using (TcpClient client = await listener.AcceptTcpClientAsync()){Console.WriteLine("客户端已连接。");NetworkStream stream = client.GetStream();// 接收数据byte[] buffer = new byte[1024];int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);string receivedMessage = Encoding.UTF8.GetString(buffer, 0, bytesRead);Console.WriteLine($"收到消息:{receivedMessage}");// 发送回应string response = "Hello from server!";byte[] responseBytes = Encoding.UTF8.GetBytes(response);await stream.WriteAsync(responseBytes, 0, responseBytes.Length);Console.WriteLine("已发送回应。");}listener.Stop();}static void Main(string[] args){Task.Run(() => StartServer()).Wait();}
}
2.3.2. 客户端(TCP)
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;class SocketClient
{public static async Task StartClient(){using (TcpClient client = new TcpClient()){Console.WriteLine("尝试连接到服务器...");await client.ConnectAsync("127.0.0.1", 5000);Console.WriteLine("已连接到服务器。");NetworkStream stream = client.GetStream();// 发送数据string message = "Hello from client!";byte[] messageBytes = Encoding.UTF8.GetBytes(message);await stream.WriteAsync(messageBytes, 0, messageBytes.Length);Console.WriteLine("已发送消息。");// 接收回应byte[] buffer = new byte[1024];int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);string response = Encoding.UTF8.GetString(buffer, 0, bytesRead);Console.WriteLine($"收到回应:{response}");}}static void Main(string[] args){Task.Run(() => StartClient()).Wait();}
}
2.4. 使用场景
需要跨不同机器或网络通信的应用程序。
实时通信,如聊天应用、游戏服务器等。
需要灵活控制通信协议和数据格式的场景。
3. 内存映射文件(Memory-Mapped Files)
3.1. 概述
内存映射文件允许多个进程共享同一块内存区域,实现高效的数据交换。它适用于需要频繁、快速共享大量数据的场景。
3.2. 特点
高性能:通过共享内存实现快速数据交换。
简单的数据共享:适用于需要在多个进程间共享复杂数据结构的应用程序。
跨语言支持:不同编程语言的进程可以通过内存映射文件进行通信。
3.3. 实现方式
3.3.1. 创建内存映射文件(服务器端)
using System;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Threading;class MemoryMappedFileServer
{static void Main(string[] args){using (var mmf = MemoryMappedFile.CreateOrOpen("SharedMemory", 1024)){Console.WriteLine("服务器已启动,等待消息...");using (var accessor = mmf.CreateViewAccessor()){while (true){byte[] buffer = new byte[256];accessor.ReadArray(0, buffer, 0, buffer.Length);string message = Encoding.UTF8.GetString(buffer).TrimEnd('\0');if (!string.IsNullOrEmpty(message)){Console.WriteLine($"收到消息:{message}");// 清空消息accessor.WriteArray(0, new byte[256], 0, 256);// 发送回应string response = "Hello from server!";byte[] responseBytes = Encoding.UTF8.GetBytes(response);accessor.WriteArray(0, responseBytes, 0, responseBytes.Length);Console.WriteLine("已发送回应。");}Thread.Sleep(1000); // 等待一段时间再检查}}}}
}
3.3.2. 读取内存映射文件(客户端)
using System;
using System.IO.MemoryMappedFiles;
using System.Text;
using System.Threading.Tasks;class MemoryMappedFileClient
{static async Task Main(string[] args){using (var mmf = MemoryMappedFile.OpenExisting("SharedMemory")){using (var accessor = mmf.CreateViewAccessor()){// 发送消息string message = "Hello from client!";byte[] messageBytes = Encoding.UTF8.GetBytes(message);accessor.WriteArray(0, messageBytes, 0, messageBytes.Length);Console.WriteLine("已发送消息。");// 等待回应while (true){byte[] buffer = new byte[256];accessor.ReadArray(0, buffer, 0, buffer.Length);string response = Encoding.UTF8.GetString(buffer).TrimEnd('\0');if (!string.IsNullOrEmpty(response)){Console.WriteLine($"收到回应:{response}");// 清空回应accessor.WriteArray(0, new byte[256], 0, 256);break;}await Task.Delay(500);}}}}
}
3.4. 使用场景
需要在多个进程间高效共享大量数据。
实时数据交换,如视频流、实时监控数据等。
复杂数据结构的共享,如图像数据、结构化信息等。
4. 信号和消息(Windows Messages)
4.1. 概述
在 Windows 环境下,进程可以通过发送和接收窗口消息来进行通信。这种方法通常用于 GUI 应用程序之间的简单通信。
4.2. 特点
适用于 GUI 应用:主要用于具有窗口的应用程序之间的通信。
简单实现:适合于发送简单的消息或命令。
4.3. 实现方式
4.3.1. 发送消息(发送方)
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;class MessageSender
{// 引入 SendMessage 函数[DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);// 自定义消息public const uint WM_USER = 0x0400;public const uint WM_CUSTOM = WM_USER + 1;static void Main(string[] args){// 获取目标窗口句柄,可以通过窗口标题查找IntPtr hWnd = FindWindow(null, "接收消息的窗口标题");if (hWnd != IntPtr.Zero){string message = "Hello from sender!";byte[] msgBytes = Encoding.UTF8.GetBytes(message);IntPtr lParam = Marshal.AllocHGlobal(msgBytes.Length + 1);Marshal.Copy(msgBytes, 0, lParam, msgBytes.Length);Marshal.WriteByte(lParam, msgBytes.Length, 0); // 添加 null 终止符SendMessage(hWnd, WM_CUSTOM, IntPtr.Zero, lParam);Marshal.FreeHGlobal(lParam);Console.WriteLine("已发送消息。");}else{Console.WriteLine("未找到目标窗口。");}}// 引入 FindWindow 函数[DllImport("user32.dll", SetLastError = true)]public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
}
4.3.2. 接收消息(接收方)
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;class MessageReceiver : Form
{// 自定义消息public const uint WM_USER = 0x0400;public const uint WM_CUSTOM = WM_USER + 1;// 引入 WndProcprotected override void WndProc(ref Message m){if (m.Msg == WM_CUSTOM){// 获取消息内容int length = 0;while (Marshal.ReadByte(m.LParam, length) != 0) length++;byte[] buffer = new byte[length];Marshal.Copy(m.LParam, buffer, 0, length);string receivedMessage = Encoding.UTF8.GetString(buffer);MessageBox.Show($"收到消息:{receivedMessage}");}base.WndProc(ref m);}[STAThread]static void Main(){Application.EnableVisualStyles();Application.Run(new MessageReceiver());}
}
4.4. 使用场景
简单的 GUI 应用程序之间的通信。
发送简单的命令或通知。
不需要高性能或大量数据传输的场景。
5. 内存映射数据结构(Memory-Mapped Data Structures)
5.1. 概述
除了简单的数据交换,进程间还可以共享复杂的数据结构,如对象、数组等。通过内存映射文件,可以实现多个进程共享相同的内存空间,进而共享数据结构。
5.2. 特点
高效数据共享:适用于需要共享复杂数据结构的场景。
实时更新:数据在共享内存中实时更新,适用于需要实时同步数据的应用。
5.3. 实现方式
5.3.1. 共享类库
创建一个共享的类库,定义数据结构,并确保它们在内存映射文件中正确对齐和序列化。
5.3.2. 服务器端(共享数据写入)
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using System.Text;class SharedData
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]public string Message;
}class MemoryMappedFileServer
{static void Main(string[] args){using (var mmf = MemoryMappedFile.CreateOrOpen("SharedData", Marshal.SizeOf(typeof(SharedData)))){using (var accessor = mmf.CreateViewAccessor()){SharedData data = new SharedData { Message = "Hello from server!" };accessor.Write(0, ref data);Console.WriteLine("已写入共享数据。");}Console.WriteLine("按任意键退出...");Console.ReadKey();}}
}
5.3.3. 客户端(共享数据读取)
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using System.Text;class SharedData
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]public string Message;
}class MemoryMappedFileClient
{static void Main(string[] args){using (var mmf = MemoryMappedFile.OpenExisting("SharedData")){using (var accessor = mmf.CreateViewAccessor()){SharedData data = new SharedData();accessor.Read(0, ref data);Console.WriteLine($"收到共享数据:{data.Message}");}}}
}
5.4. 使用场景
需要共享复杂数据结构或大量数据的进程间通信。
实时数据同步,如监控系统、实时数据分析等。
6. Windows Communication Foundation (WCF)
6.1. 概述
WCF 是一个用于构建服务导向应用程序的框架,支持多种传输协议和消息格式。它适用于需要跨平台、跨网络通信的复杂应用程序。
6.2. 特点
多协议支持:支持 HTTP, TCP, Named Pipes 等多种传输协议。
灵活性高:可配置性强,适用于不同的通信需求。
安全性:内置多种安全机制,如消息加密、身份验证等。
6.3. 实现方式
6.3.1. 定义服务契约
using System.ServiceModel;[ServiceContract]
public interface IMyService
{[OperationContract]string GetMessage(string name);
}
6.3.2. 实现服务
public class MyService : IMyService
{public string GetMessage(string name){return $"Hello, {name}!";}
}
6.3.3. 配置服务
App.config(服务器端)
<configuration><system.serviceModel><services><service name="MyService"><endpoint address="" binding="netNamedPipeBinding" contract="IMyService" /><host><baseAddresses><add baseAddress="net.pipe://localhost/MyService" /></baseAddresses></host></service></services><bindings><netNamedPipeBinding><binding name="NamedPipeBinding" /></netNamedPipeBinding></bindings></system.serviceModel>
</configuration>
6.3.4. 启动服务
using System;
using System.ServiceModel;class Program
{static void Main(string[] args){using (ServiceHost host = new ServiceHost(typeof(MyService))){host.Open();Console.WriteLine("服务已启动。按任意键退出...");Console.ReadKey();}}
}
6.3.5. 客户端调用
using System;
using System.ServiceModel;class Program
{static void Main(string[] args){var binding = new NetNamedPipeBinding();var endpoint = new EndpointAddress("net.pipe://localhost/MyService");ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>(binding, endpoint);IMyService proxy = factory.CreateChannel();string response = proxy.GetMessage("Client");Console.WriteLine($"服务器回应:{response}");((IClientChannel)proxy).Close();factory.Close();}
}
6.4. 使用场景
需要跨网络或跨平台的复杂服务通信。
需要高级的安全性和可靠性。
构建服务导向架构(Service-Oriented Architecture, SOA)的应用程序。
7. 信号R(SignalR)
7.1. 概述
SignalR 是一个用于构建实时 Web 功能的库,虽然主要用于 Web 应用,但也可以用于桌面应用程序间的实时通信。
7.2. 特点
实时通信:支持实时数据传输,如聊天应用、实时监控等。
简化的 API:提供高层次的 API,简化实时通信的实现。
跨平台:支持多种客户端,包括 .NET、JavaScript、Java 等。
7.3. 实现方式
7.3.1. 服务器端(Hub)
using Microsoft.AspNetCore.SignalR;public class ChatHub : Hub
{public async Task SendMessage(string user, string message){await Clients.All.SendAsync("ReceiveMessage", user, message);}
}
7.3.2. 配置服务器
Startup.cs
public class Startup
{public void ConfigureServices(IServiceCollection services){services.AddSignalR();}public void Configure(IApplicationBuilder app, IWebHostEnvironment env){app.UseRouting();app.UseEndpoints(endpoints =>{endpoints.MapHub<ChatHub>("/chatHub");});}
}
7.3.3. 客户端(C#)
using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Threading.Tasks;class Program
{static async Task Main(string[] args){var connection = new HubConnectionBuilder().WithUrl("http://localhost:5000/chatHub").Build();connection.On<string, string>("ReceiveMessage", (user, message) =>{Console.WriteLine($"{user}: {message}");});await connection.StartAsync();Console.WriteLine("已连接到服务器。");while (true){string input = Console.ReadLine();if (input == "exit") break;await connection.InvokeAsync("SendMessage", "Client", input);}await connection.StopAsync();}
}
7.4. 使用场景
实时数据更新,如股票行情、实时监控系统。
聊天应用、多人游戏等需要即时交互的应用。
需要实时通知和推送的桌面或移动应用。
8. 共享数据库
8.1. 概述
通过使用一个共享的数据库,两个进程可以通过读写数据库中的数据来实现通信。这种方法简单且可靠,适用于不需要实时通信的场景。
8.2. 特点
简单实现:利用现有的数据库系统,无需额外的通信机制。
持久性:数据持久存储,适用于需要记录通信历史的应用。
跨平台支持:适用于不同操作系统和编程语言的进程。
8.3. 实现方式
8.3.1. 发送方写入数据
using System;
using System.Data.SqlClient;class DatabaseSender
{static void Main(string[] args){string connectionString = "Server=your_server;Database=your_db;User Id=your_user;Password=your_password;";using (SqlConnection connection = new SqlConnection(connectionString)){connection.Open();string insertQuery = "INSERT INTO Messages (Sender, Content, Timestamp) VALUES (@sender, @content, @timestamp)";using (SqlCommand command = new SqlCommand(insertQuery, connection)){command.Parameters.AddWithValue("@sender", "SenderProcess");command.Parameters.AddWithValue("@content", "Hello from sender!");command.Parameters.AddWithValue("@timestamp", DateTime.Now);command.ExecuteNonQuery();Console.WriteLine("已发送消息到数据库。");}}}
}
8.3.2. 接收方读取数据
using System;
using System.Data.SqlClient;class DatabaseReceiver
{static void Main(string[] args){string connectionString = "Server=your_server;Database=your_db;User Id=your_user;Password=your_password;";using (SqlConnection connection = new SqlConnection(connectionString)){connection.Open();string selectQuery = "SELECT Sender, Content, Timestamp FROM Messages ORDER BY Timestamp DESC";using (SqlCommand command = new SqlCommand(selectQuery, connection)){using (SqlDataReader reader = command.ExecuteReader()){while (reader.Read()){string sender = reader.GetString(0);string content = reader.GetString(1);DateTime timestamp = reader.GetDateTime(2);Console.WriteLine($"{timestamp} - {sender}: {content}");}}}}}
}
8.4. 使用场景
不需要实时通信但需要可靠数据交换的应用程序。
需要记录通信历史或数据持久性的场景。
多个进程或服务需要共享大量数据。
8.5. 注意事项
性能:数据库通信通常比内存共享或管道通信更慢,适合不频繁的数据交换。
并发控制:需要处理多进程对数据库的并发访问,确保数据一致性。
安全性:确保数据库连接的安全性,防止未经授权的访问。
9. Windows API(Windows Messages)
9.1. 概述
利用 Windows API 发送和接收消息也是一种 IPC 方式,特别适用于 GUI 应用程序之间的通信。
9.2. 特点
适用于 GUI 应用:主要用于具有窗口句柄的应用程序。
简单实现:适合发送简单命令或通知。
9.3. 实现方式
9.3.1. 发送消息(发送方)
using System;
using System.Runtime.InteropServices;class MessageSender
{// 引入 SendMessage 函数[DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);// 自定义消息public const uint WM_USER = 0x0400;public const uint WM_CUSTOM = WM_USER + 1;// 引入 FindWindow 函数[DllImport("user32.dll", SetLastError = true)]public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);static void Main(string[] args){// 获取目标窗口句柄,可以通过窗口标题查找IntPtr hWnd = FindWindow(null, "接收消息的窗口标题");if (hWnd != IntPtr.Zero){string message = "Hello from sender!";byte[] msgBytes = System.Text.Encoding.UTF8.GetBytes(message);IntPtr lParam = Marshal.AllocHGlobal(msgBytes.Length + 1);Marshal.Copy(msgBytes, 0, lParam, msgBytes.Length);Marshal.WriteByte(lParam, msgBytes.Length, 0); // 添加 null 终止符SendMessage(hWnd, WM_CUSTOM, IntPtr.Zero, lParam);Marshal.FreeHGlobal(lParam);Console.WriteLine("已发送消息。");}else{Console.WriteLine("未找到目标窗口。");}}
}
9.3.2. 接收消息(接收方)
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;class MessageReceiver : Form
{// 自定义消息public const uint WM_USER = 0x0400;public const uint WM_CUSTOM = WM_USER + 1;// 重写 WndProc 方法以处理自定义消息protected override void WndProc(ref Message m){if (m.Msg == WM_CUSTOM){// 获取消息内容int length = 0;while (Marshal.ReadByte(m.LParam, length) != 0) length++;byte[] buffer = new byte[length];Marshal.Copy(m.LParam, buffer, 0, length);string receivedMessage = Encoding.UTF8.GetString(buffer);MessageBox.Show($"收到消息:{receivedMessage}");}base.WndProc(ref m);}[STAThread]static void Main(){Application.EnableVisualStyles();Application.Run(new MessageReceiver());}
}
9.4. 使用场景
简单的 GUI 应用程序之间的通信。
发送简单的命令或通知。
不需要高性能或大量数据传输的场景。
9.5. 注意事项
窗口句柄:需要获取目标窗口的句柄(Handle),可以通过窗口标题或类名查找。
消息格式:确保发送方和接收方对消息格式有一致的约定。
安全性:避免发送恶意消息,确保消息的合法性。
10. 其他 IPC 方法
10.1. COM(Component Object Model)
概述:COM 是微软的一种组件软件架构,用于不同进程或不同编程语言间的对象通信。
特点:跨语言、跨进程、支持对象导向。
使用场景:需要复杂对象交互和跨语言支持的场景。
缺点:配置复杂,学习曲线陡峭。
10.2. 共享数据库
概述:通过共享数据库(如 SQL Server, SQLite, MySQL)进行数据交换。
特点:数据持久化、易于管理、跨平台。
使用场景:不需要实时通信但需要可靠数据交换的场景。
缺点:性能较低,不适合高频率数据交换。
10.3. 文件系统
概述:通过在文件系统中读写文件来实现通信。
特点:实现简单、无需特殊配置。
使用场景:简单的数据交换,如配置文件、日志记录等。
缺点:不适合实时通信,性能较低,易受文件锁定影响。
11. 性能和安全性考虑
11.1. 性能优化
选择合适的 IPC 方法:根据通信需求(数据量、实时性、跨网络等)选择最合适的 IPC 方法。
减少数据传输量:只传输必要的数据,避免冗余传输。
使用高效的数据格式:如二进制格式代替文本格式,减少解析开销。
并发处理:利用异步编程和并发机制,提升数据处理效率。
11.2. 安全性
身份验证:确保只有授权的进程可以进行通信。
数据加密:在传输敏感数据时,使用加密机制保护数据安全。
访问控制:设置严格的访问权限,防止未授权的访问和操作。
防止注入攻击:验证和清理接收到的数据,防止恶意代码注入。
12. 总结
C# 提供了多种进程间通信(IPC)方法,涵盖了从简单的数据交换到复杂的实时通信需求。选择合适的 IPC 方法需要根据具体的应用场景、性能需求和安全要求来决定。以下是常见 IPC 方法的简要对比:
IPC 方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
命名管道 | 高效、支持双向通信、可跨网络 | 仅限于同一台机器或局域网 | 高效数据传输、双向通信 |
套接字(Sockets) | 灵活、支持多协议、跨平台 | 实现复杂、需要处理网络延迟和安全性 | 跨网络通信、实时应用如聊天和游戏 |
内存映射文件 | 高性能、适合共享大量数据 | 需要处理内存管理和同步问题 | 实时数据共享、大量数据交换 |
信号和消息 | 简单、适用于 GUI 应用 | 仅适用于具有窗口句柄的应用,有限的数据传输能力 | 简单命令或通知的 GUI 应用通信 |
WCF | 多协议支持、高度可配置、安全性强 | 配置复杂、学习曲线陡峭 | 复杂服务通信、跨平台和跨语言应用 |
SignalR | 实时通信、简化的 API、跨平台 | 主要用于 Web 应用,桌面应用需要额外配置 | 实时数据更新、聊天应用、实时监控系统 |
共享数据库 | 数据持久化、易于管理、跨平台 | 性能较低、不适合高频率实时通信 | 可靠的数据交换、需要记录通信历史的场景 |
文件系统 | 实现简单、无需特殊配置 | 不适合实时通信、性能低、易受文件锁定影响 | 简单的数据交换、配置文件和日志记录 |
COM | 跨语言、支持复杂对象交互 | 配置复杂、学习曲线陡峭 | 需要复杂对象交互和跨语言支持的场景 |
相关文章:
C# 两个进程/exe通讯方式 两个应用程序通讯方式
C# 两个exe通讯方式 两个应用程序通讯方式 1. 命名管道(Named Pipes) 1.1. 概述 命名管道是一种用于在同一台机器或网络中不同进程之间进行双向通信的机制。它支持同步和异步通信,适用于需要高效数据传输的场景。 1.2. 特点 双向通信&am…...

ubuntu下打开摄像头
ubuntu下打开摄像头 在Ubuntu下,你可以使用cheese,这是一个开源的摄像头应用程序。如果你还没有安装它,可以通过以下命令安装: sudo apt-get updatesudo apt-get install cheese 安装完成后,你可以通过命令行启动它: cheese 或者,你也可以使用ffmpeg来打开摄像头并进…...

ABAP 表转JSON格式
FUNCTION ZRFC_FI_SEND_PAYPLAN2BPM. *"---------------------------------------------------------------------- *"*"本地接口: *" IMPORTING *" VALUE(INPUT) TYPE ZSRFC_FI_SEND_PAYBPM_IN *" EXPORTING *" VAL…...

oceanbase的日志量太大,撑爆磁盘,修改下日志级别
oceanbase的日志量太大,撑爆磁盘,修改下日志级别: [adminlnpg ~]$ obclient -h127.0.0.1 -uroot -P2881 -plinux123 Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 3221561020 Server version: O…...
【C++11】lambda表达式
前言: 随着 C11 的发布,C 标准引入了许多新特性,使语言更加现代化,开发者编写的代码也变得更加简洁和易于维护。Lambda 表达式是其中一个重要的特性,它提供了一种方便的方式来定义匿名函数,这在函数式编程范…...

前端学习-css的背景(十六)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 背景颜色 语法格式 背景图片 语法格式 背景平铺 语法格式 背景图片位置 语法格式 参数代表的意思 参数是方位名词 参数是精确单位 参数是混合单位 背…...

使用Postman搞定各种接口token实战
现在许多项目都使用jwt来实现用户登录和数据权限,校验过用户的用户名和密码后,会向用户响应一段经过加密的token,在这段token中可能储存了数据权限等,在后期的访问中,需要携带这段token,后台解析这段token才…...

ssh连接慢的问题或远程连接服务超时
问题原因: 在SSH登录过程中,服务器会通过反向DNS查找客户端的主机名,然后与登录的IP地址进行匹配,以验证登录的合法性。如果客户端的IP没有域名或DNS服务器响应缓慢,这可能导致SSH登录过慢。为了解决这个问题…...

基于卷积神经网络的蔬菜识别系统,resnet50,mobilenet模型【pytorch框架+python源码】
更多目标检测和图像分类识别项目可看我主页其他文章 功能演示: 基于卷积神经网络的蔬菜识别系统,resnet50,mobilenet【pytorch框架,python,tkinter】_哔哩哔哩_bilibili (一)简介 基于卷积神…...

数据结构与算法:栈与队列的高级应用
目录 3.1 栈的高级用法 3.2 队列的深度应用 3.3 栈与队列的综合应用 总结 数据结构与算法:栈与队列的高级应用 栈和队列是两种重要的线性数据结构,它们在计算机科学和工程的许多领域都有广泛的应用。从函数调用到表达式求值,再到任务调度…...
macos php开发环境之macport安装的php扩展安装,php常用扩展安装,port中可用的所有php扩展列表
macos中,我们使用了port 安装了php后,默认只带有php基本的核心扩展的, 如果需要使用其他的扩展,如 redis, https, xdebug等扩展就需要我们手动来安装对应的扩展。 macos php开发环境 macport安装的php的方法见macos 中…...

使用Pytorch+Numpy+Matplotlib实现手写字体分类和图像显示
文章目录 1.引用2.内置图片数据集加载3.处理为batch类型4.设置运行设备5.查看数据6.绘图查看数据图片(1)不显示图片标签(2)打印图片标签(3)图片显示标签 7.定义卷积函数8.卷积实例化、损失函数、优化器9.训练和测试损失、正确率(1)训练(2)测试(3)循环(4)损失和正确率曲线(5)输出…...
kimi帮我解决ubuntu下软链接文件夹权限不够的问题
我的操作如下 ubuntuubuntu-QiTianM420-N000:~$ ln -s /media/ubuntu/4701aea3-f883-40a9-b12f-61e832117414 code ubuntuubuntu-QiTianM420-N000:~$ ls -l 总用量 636 drwxrwxr-x 2 ubuntu ubuntu 4096 5月 7 17:16 bin drwxrwxrwx 2 ubuntu ubuntu 4096 5月 8 13…...

如何去除背景音乐保留人声?保留人声,消除杂音
在日常生活和工作中,我们经常遇到需要处理音频的情况,尤其是当我们想要去除背景音乐,仅保留人声时。这种需求在处理电影片段、制作音乐MV、或者提取演讲内容等场景中尤为常见。本文将为您详细介绍如何去除背景音乐并保留人声,帮助…...
2.4.ReactOS系统提升IRQL级别KfRaiseIrql 函数
2.4.ReactOS系统提升IRQL级别KfRaiseIrql 函数 2.4.ReactOS系统提升IRQL级别KfRaiseIrql 函数 文章目录 2.4.ReactOS系统提升IRQL级别KfRaiseIrql 函数KfRaiseIrql 函数 KfRaiseIrql 函数 /*********************************************************************** NAME …...

【新书】使用 OpenAI API 构建 AI 应用:利用 ChatGPT等构建 10 个 AI 项目(第二版),404页pdf
通过构建 ChatGPT 克隆、代码错误修复器、测验生成器、翻译应用、自动回复邮件生成器、PowerPoint 生成器等项目,提升您的应用开发技能。 关键特性 通过掌握 ChatGPT 概念(包括微调和集成),转变为 AI 开发专家 通过涵盖广泛 AI …...
修改PostgreSQL表中的字段排列顺序
二、通过修改系统表(pg_attribute)达到字段重新排序的目的有关系统表的概述及用途可以查看官网:http://www.pgsqldb.org/pgsqldoc-cvs/catalogs.html 表名字表用途pg_class表,索引,序列,视图(”关系”)pg_…...

canvas实现手写功能
1.从接口获取手写内容,处理成由单个字组成的数组(包括符号) 2.合成所有图的时候,会闪现outputCanvas合成的图,注意隐藏 3.可以进行多个手写内容切换 4.基于uniapp的 <template><view class"content&quo…...
Python知识点:基于Python技术,如何使用TensorFlow进行目标检测
开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! 使用TensorFlow进行目标检测的完整指南 目标检测是计算机视觉领域中的一项重要任…...

初始爬虫13(js逆向)
为了解决网页端的动态加载,加密设置等,所以需要js逆向操作。 JavaScript逆向可以分为三大部分:寻找入口,调试分析和模拟执行。 1.chrome在爬虫中的作用 1.1preserve log的使用 默认情况下,页面发生跳转之后…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...