|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Runtime.InteropServices;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
using System;
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
namespace IPCLib
|
|
|
{
|
|
|
// SharedMemoryStruct.cs - 最终修复版
|
|
|
|
|
|
/// <summary>
|
|
|
/// 共享内存头部结构(控制区)
|
|
|
/// ✅ 所有字段都是值类型,无引用类型
|
|
|
/// </summary>
|
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
public struct SharedMemoryHeader
|
|
|
{
|
|
|
public int IsLocked;
|
|
|
public long A_LastHeartbeat;
|
|
|
public long B_LastHeartbeat;
|
|
|
public long A_SessionId;
|
|
|
public long B_SessionId;
|
|
|
public int A_HasData;
|
|
|
public int B_HasData;
|
|
|
public int A_DataLength;
|
|
|
public int B_DataLength;
|
|
|
public long A_SequenceId;
|
|
|
public long B_SequenceId;
|
|
|
public int ConnectionStatus;
|
|
|
public long Reserved1;
|
|
|
public long Reserved2;
|
|
|
public long Reserved3;
|
|
|
public long Reserved4;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 数据包结构(1024 字节)
|
|
|
/// ✅ 修复:使用固定大小缓冲区替代数组
|
|
|
/// </summary>
|
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
|
public unsafe struct DataPacket
|
|
|
{
|
|
|
public long Timestamp; // 8 字节
|
|
|
public int DataType; // 4 字节
|
|
|
public int DataLength; // 4 字节
|
|
|
public long SequenceId; // 8 字节
|
|
|
|
|
|
// ✅ 修复:使用固定大小缓冲区(1000 字节)
|
|
|
public fixed byte Data[1000]; // 固定缓冲区,不是引用类型
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 内存布局常量
|
|
|
/// </summary>
|
|
|
public static class MemoryLayout
|
|
|
{
|
|
|
public const int HeaderSize = 256;
|
|
|
public const int PacketSize = 1024;
|
|
|
public const int AToBOffset = HeaderSize;
|
|
|
public const int BToAOffset = HeaderSize + PacketSize;
|
|
|
public const int TotalSize = HeaderSize + PacketSize * 2;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 辅助工具类
|
|
|
/// </summary>
|
|
|
public static class SharedMemoryHelper
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 将字符串写入固定缓冲区
|
|
|
/// </summary>
|
|
|
public static unsafe void WriteToFixedBuffer(byte* buffer, string text, int maxLength = 1000)
|
|
|
{
|
|
|
// 清空缓冲区
|
|
|
for (int i = 0; i < maxLength; i++)
|
|
|
{
|
|
|
buffer[i] = 0;
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrEmpty(text))
|
|
|
return;
|
|
|
|
|
|
byte[] bytes = Encoding.UTF8.GetBytes(text);
|
|
|
int copyLength = Math.Min(bytes.Length, maxLength);
|
|
|
|
|
|
for (int i = 0; i < copyLength; i++)
|
|
|
{
|
|
|
buffer[i] = bytes[i];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 从固定缓冲区读取字符串
|
|
|
/// </summary>
|
|
|
public static unsafe string ReadFromFixedBuffer(byte* buffer, int length)
|
|
|
{
|
|
|
if (length <= 0)
|
|
|
return string.Empty;
|
|
|
|
|
|
int actualLength = Math.Min(length, 1000);
|
|
|
byte[] bytes = new byte[actualLength];
|
|
|
|
|
|
for (int i = 0; i < actualLength; i++)
|
|
|
{
|
|
|
bytes[i] = buffer[i];
|
|
|
}
|
|
|
|
|
|
return Encoding.UTF8.GetString(bytes);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将字符串转换为字节数组(用于非 unsafe 场景)
|
|
|
/// </summary>
|
|
|
public static byte[] StringToBytes(string text, int maxLength = 1000)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(text))
|
|
|
return new byte[maxLength];
|
|
|
|
|
|
byte[] bytes = Encoding.UTF8.GetBytes(text);
|
|
|
byte[] result = new byte[maxLength];
|
|
|
Array.Copy(bytes, result, Math.Min(bytes.Length, maxLength));
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 将字节数组转换为字符串
|
|
|
/// </summary>
|
|
|
public static string BytesToString(byte[] bytes, int length)
|
|
|
{
|
|
|
if (bytes == null || length <= 0)
|
|
|
return string.Empty;
|
|
|
|
|
|
return Encoding.UTF8.GetString(bytes, 0, Math.Min(length, bytes.Length));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public enum ConnectionStatus
|
|
|
{
|
|
|
Disconnected = 0, // 断开(硬断开,不可恢复)
|
|
|
Connecting = 1, // 连接中
|
|
|
Connected = 2, // 正常连接
|
|
|
Warning = 3, // ⚠️ 警告:心跳延迟(可恢复)
|
|
|
SoftDisconnected = 4, // 🔄 软断开:超时但未确认退出(可恢复)
|
|
|
Frozen = 5 // ❄️ 死机:长时间无响应
|
|
|
}
|
|
|
}
|