C# 的进程间通信(IPC,Inter-Process Communication)

🧭 一、IPC 是什么?

IPC(Inter-Process Communication) 是指:

在同一台计算机上,不同进程之间传递数据、信号或消息的机制。

常见用途:

  • C# 主程序与后台服务通信

  • GUI 应用与命令行程序交互、

  • 前端与后端(不同进程)传输 JSON

  • 与 C++、Python、Java 等跨语言进程通信


🧩 二、C# 支持的 IPC 方式总览

|-------------------------------------------|---------------------|------|-------|------------------|
| IPC方式 | 平台 | 性能 | 是否跨平台 | 特点 |
| Named Pipe(命名管道) | Windows/Linux/macOS | ⭐⭐⭐⭐ | ✅ | 速度快,操作系统原生支持 |
| Memory-Mapped File(内存映射文件) | Windows/Linux | ⭐⭐⭐⭐ | ✅ | 共享大块数据最快方式 |
| Socket(TCP/UDP) | 所有平台 | ⭐⭐⭐ | ✅ | 通用性最强,可跨机器 |
| gRPC / HTTP / REST | 所有平台 | ⭐⭐ | ✅ | 最易用,跨语言;性能较低 |
| MessageQueue / ZeroMQ / RabbitMQ | 所有平台 | ⭐⭐⭐ | ✅ | 异步、高并发;复杂度高 |
| WCF(Windows Communication Foundation) | Windows | ⭐⭐⭐ | ❌ | 功能强,但已不推荐用于新项目 |
| SignalR / WebSocket | 所有平台 | ⭐⭐⭐ | ✅ | 实时通信、配合 Web 应用常用 |


⚙️ 三、常用实现方式详解 + 示例


Named Pipe(命名管道)

📦 适用场景: 同一台机器上两个进程通信

📈 优点: 速度快、无需网络栈、支持字符串与二进制

🧩 跨平台: ✅(.NET 5+)

▶ Server(服务端)
复制代码
using System.IO.Pipes;
using System.Text;

class PipeServer
{
    static void Main()
    {
        using var server = new NamedPipeServerStream("MyPipe", PipeDirection.InOut, 1);
        Console.WriteLine("等待客户端连接...");
        server.WaitForConnection();

        using var reader = new StreamReader(server, Encoding.UTF8);
        using var writer = new StreamWriter(server, Encoding.UTF8) { AutoFlush = true };

        Console.WriteLine("客户端已连接");
        while (true)
        {
            string? msg = reader.ReadLine();
            if (msg == null || msg == "exit") break;
            Console.WriteLine($"收到: {msg}");
            writer.WriteLine($"服务器收到: {msg}");
        }
    }
}
▶ Client(客户端)
复制代码
using System.IO.Pipes;
using System.Text;

class PipeClient
{
    static void Main()
    {
        using var client = new NamedPipeClientStream(".", "MyPipe", PipeDirection.InOut);
        client.Connect();

        using var reader = new StreamReader(client, Encoding.UTF8);
        using var writer = new StreamWriter(client, Encoding.UTF8) { AutoFlush = true };

        for (int i = 0; i < 3; i++)
        {
            writer.WriteLine($"消息 {i}");
            Console.WriteLine(reader.ReadLine());
        }

        writer.WriteLine("exit");
    }
}

✅ 特点:

  • 多个客户端可连接同一个管道(指定 maxNumberOfServerInstances
  • 支持异步版本:WaitForConnectionAsync()ReadAsync()
  • 适合进程间命令传递或 JSON 消息传输

Memory-Mapped File(内存映射文件)

📦 适用场景: 需要共享大块数据(如图像、缓存)

📈 优点: 读写极快

📉 缺点: 需要同步机制防止并发问题

▶ 写入进程
复制代码
using System.IO.MemoryMappedFiles;
using System.Text;

class Writer
{
    static void Main()
    {
        using var mmf = MemoryMappedFile.CreateOrOpen("SharedMemory", 1024);
        using var accessor = mmf.CreateViewAccessor();

        string message = "Hello from Process A";
        byte[] bytes = Encoding.UTF8.GetBytes(message);
        accessor.WriteArray(0, bytes, 0, bytes.Length);

        Console.WriteLine("写入完成");
        Console.ReadLine();
    }
}
▶ 读取进程
复制代码
using System.IO.MemoryMappedFiles;
using System.Text;

class Reader
{
    static void Main()
    {
        using var mmf = MemoryMappedFile.OpenExisting("SharedMemory");
        using var accessor = mmf.CreateViewAccessor();

        byte[] buffer = new byte[1024];
        accessor.ReadArray(0, buffer, 0, buffer.Length);

        Console.WriteLine("读取内容: " + Encoding.UTF8.GetString(buffer).TrimEnd('\0'));
    }
}

Socket(TCP)

📦 适用场景: 不仅限于本机,可跨网络通信

📈 优点: 通用性最强

📉 缺点: 需要管理连接、心跳、序列化等

▶ Server
复制代码
using System.Net;
using System.Net.Sockets;
using System.Text;

class TcpServer
{
    static async Task Main()
    {
        var listener = new TcpListener(IPAddress.Loopback, 5000);
        listener.Start();
        Console.WriteLine("等待客户端...");
        var client = await listener.AcceptTcpClientAsync();

        using var stream = client.GetStream();
        byte[] buffer = new byte[1024];
        int len = await stream.ReadAsync(buffer);
        Console.WriteLine("收到: " + Encoding.UTF8.GetString(buffer, 0, len));
    }
}
▶ Client
复制代码
using System.Net.Sockets;
using System.Text;

class TcpClientDemo
{
    static async Task Main()
    {
        var client = new TcpClient();
        await client.ConnectAsync("127.0.0.1", 5000);

        using var stream = client.GetStream();
        byte[] data = Encoding.UTF8.GetBytes("Hello Server");
        await stream.WriteAsync(data);
    }
}

gRPC / HTTP / SignalR

📦 适用场景: 跨平台、跨语言通信(如 C# ↔ Python)

🧩 实现: 使用 ASP.NET Core Web API 或 gRPC 服务

📈 优点: 简单直观、兼容多语言

📉 缺点: 性能不如管道 / 内存映射


🧠 四、选型建议(按场景)

|----------------|-----------------------------------|---------|
| 场景 | 推荐方式 | 说明 |
| 同机 C# ↔ C# 通信 | Named Pipe | 简单高效 |
| 同机 C# ↔ C++ 通信 | Named Pipe 或 MemoryMappedFile | 跨语言易实现 |
| 多机通信 | Socket / gRPC | 通用 |
| GUI ↔ 后台守护进程 | Named Pipe + JSON 消息 | 稳定、方便调试 |
| 高速数据共享(如图像帧) | Memory-Mapped File | 低延迟 |


🧰 五、调试与编码注意点

  1. 统一编码
    使用 Encoding.UTF8,避免乱码。

  2. 结构化数据
    使用 JSON(System.Text.Json)序列化传输结构体。

    var json = JsonSerializer.Serialize(obj);

  3. 错误处理
    IPC 通常易出问题,要加超时、断线重连、异常捕获。

  4. 异步通信
    推荐使用 ReadAsync() / WriteAsync(),避免阻塞主线程。


🧩 六、JSON 通信模板(推荐现代做法)

Server:

复制代码
var server = new NamedPipeServerStream("MyPipe");
await server.WaitForConnectionAsync();

using var reader = new StreamReader(server);
using var writer = new StreamWriter(server) { AutoFlush = true };

while (true)
{
    var line = await reader.ReadLineAsync();
    if (line == null) break;

    var msg = JsonSerializer.Deserialize<Message>(line);
    Console.WriteLine($"收到指令: {msg.Command}");

    var reply = new Message { Command = "ACK", Data = "OK" };
    await writer.WriteLineAsync(JsonSerializer.Serialize(reply));
}

record Message { public string Command { get; set; } public string Data { get; set; } }
相关推荐
跟着珅聪学java2 小时前
以下是使用JavaScript动态拼接数组内容到HTML的多种方法及示例:
开发语言·前端·javascript
小鸡吃米…2 小时前
Python - 扩展
开发语言·python
CreasyChan2 小时前
unity-向量数学:由浅入深详解
unity·c#
斯文by累2 小时前
浅析:Scheme开发语言
开发语言
IT艺术家-rookie2 小时前
golang-- sync.WaitGroup 和 errgroup.Group 详解
开发语言·后端·golang
树下水月2 小时前
Go语言编码规范
开发语言·后端·golang
无限大.2 小时前
为什么“云计算“能改变世界?——从本地计算到云端服务
开发语言·云计算·perl
草莓熊Lotso2 小时前
Python 流程控制完全指南:条件语句 + 循环语句 + 实战案例(零基础入门)
android·开发语言·人工智能·经验分享·笔记·后端·python
laozhoy12 小时前
深入理解Golang中的锁机制
开发语言·后端·golang