您好,欢迎来到叨叨游戏网。
搜索
您的当前位置:首页跨程序通讯-IPC通讯

跨程序通讯-IPC通讯

来源:叨叨游戏网

想要在两个程序之间通讯,A写入,B读取,询问豆包,给出答案,参考并改进为如下

创建共享内存类

首先,创建一个用于处理共享内存操作的类。在这个类中,将使用 System.IO.MemoryMappedFiles 命名空间下的相关类来实现共享内存功能。

using System;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;

class SharedMemoryIPC
{
    // 共享内存名称
    private const string SharedMemoryName = "MySharedMemory";
    // 共享内存大小
    private const int SharedMemorySize = 1024;

    // 创建共享内存文件映射对象
    private MemoryMappedFile _memoryMappedFile;
    // 创建共享内存视图访问器对象
    private MemoryMappedViewAccessor _viewAccessor;

    // 打开共享内存
    public bool OpenSharedMemory()
    {
        try
        {
            // 创建共享内存文件映射对象,具有读/写访问权限
            _memoryMappedFile = MemoryMappedFile.CreateOrOpen(SharedMemoryName, SharedMemorySize, MemoryMappedFileAccess.ReadWrite);
            // 创建共享内存视图访问器对象,用于访问共享内存中的数据
            _viewAccessor = _memoryMappedFile.CreateViewAccessor();
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"共享内存打开失败: {ex.Message}");
            return false;
        }
    }

    // 向共享内存中写入数据
    public bool WriteToSharedMemory(string data)
    {
        try
        {
            // 将数据转换为字节数组
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(data);
            // 确保写入的数据长度不超过共享内存大小
            if (buffer.Length <= SharedMemorySize)
            {
                // 将字节数组写入共享内存视图访问器
                _viewAccessor.WriteArray(0, buffer, 0, buffer.Length);
                return true;
            }
            else
            {
                Console.WriteLine("写入数据过长,超过共享内存大小");
                return false;
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"数据写入共享内存失败: {ex.Message}");
            return false;
        }
    }

    // 从共享内存中读取数据
    public string ReadFromSharedMemory()
    {
        try
        {
            // 创建一个字节数组来接收从共享内存读取的数据
            byte[] buffer = new byte[SharedMemorySize];
            // 从共享内存视图访问器读取数据到字节数组
            _viewAccessor.ReadArray(0, buffer, 0, SharedMemorySize);
            // 将字节数组转换为字符串并返回
            return System.Text.Encoding.UTF8.GetString(buffer).TrimEnd('\0');
        }
        catch (Exception ex)
        {
            Console.WriteLine($"从共享内存读取数据失败: {ex.Message}");
            return "";
        }
    }

    // 关闭共享内存
    public void CloseSharedMemory()
    {
        if (_viewAccessor!= null)
        {
            _viewAccessor.Dispose();
        }
        if (_memoryMappedFile!= null)
        {
            _memoryMappedFile.Dispose();
        }
    }
}

在上述类中:

  • SharedMemoryName 定义了共享内存的名称,不同进程通过这个相同的名称来访问同一共享内存段。
  • SharedMemorySize 设定了共享内存的大小,这里设置为 1024 字节。
  • OpenSharedMemory 方法用于创建或打开共享内存段,并创建访问器以便后续对共享内存进行读写操作。
  • WriteToSharedMemory 方法将传入的字符串数据转换为字节数组后写入共享内存。
  • ReadFromSharedMemory 方法从共享内存中读取数据并转换为字符串返回。
  • CloseSharedMemory 方法用于关闭共享内存视图访问器和共享内存文件映射对象,释放相关资源。

新建一个写入程序

    public partial class WriteFrm : Form
    {
        public WriteFrm()
        {
            InitializeComponent();
        }
        SharedMemoryIPC sharedMemory;
        bool isOpen = false;

        private void Form1_Load(object sender, EventArgs e)
        {
            sharedMemory = new SharedMemoryIPC();
            // 打开共享内存
            isOpen = sharedMemory.OpenSharedMemory();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (isOpen)
            {
                // 要写入共享内存的数据
                string dataToWrite = textBox1.Text;
                // 向共享内存写入数据
                if (sharedMemory.WriteToSharedMemory(dataToWrite))
                {
                    Console.WriteLine($"数据已成功写入共享内存: {dataToWrite}");
                }
                else
                {
                    Console.WriteLine("数据写入共享内存失败");
                }
            }
        }

        private void WriteFrm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 关闭共享内存
            sharedMemory.CloseSharedMemory();
        }
    }

读取程序

    public partial class ReadFrm : Form
    {
        public ReadFrm()
        {
            InitializeComponent();
        }
        SharedMemoryIPC sharedMemory;
        bool isOpen = false;
        private void ReadFrm_Load(object sender, EventArgs e)
        {
            sharedMemory = new SharedMemoryIPC();
            // 打开共享内存
            isOpen = sharedMemory.OpenSharedMemory();

        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (isOpen)
            {
                // 从共享内存读取数据
                string dataRead = sharedMemory.ReadFromSharedMemory();
                Console.WriteLine($"从共享内存读取的数据: {dataRead}");
                textBox1.Text = dataRead;
            }

        }

        private void ReadFrm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 关闭共享内存
            sharedMemory.CloseSharedMemory();
        }
    }

问题点

数据以覆盖方式写入,当第一次写入的数据长度较长,二次写入的较短时,读取数据会发现读到的有上次的数据部分

    // 清空共享内存中的数据
    public bool ClearSharedMemoryData()
    {
        try
        {
            byte[] zeroBuffer = new byte[SharedMemorySize];
            _viewAccessor.WriteArray(0, zeroBuffer, 0, SharedMemorySize);
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"清空共享内存数据失败: {ex.Message}");
            return false;
        }
    }

ClearSharedMemoryData方法创建了一个大小与共享内存相同的字节数组zeroBuffer,数组中的所有元素初始化为 0。然后使用WriteArray方法将这个字节数组写入共享内存视图访问器,从偏移量 0 开始,写入的长度为共享内存的大小SharedMemorySize,这样就将共享内存中的所有数据都设置为 0,实现了清空数据的目的。对于更复杂的情况,要根据具体情况,进行清除。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- gamedaodao.net 版权所有 湘ICP备2024080961号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务