进程间通信包创建
Posted
技术标签:
【中文标题】进程间通信包创建【英文标题】:Inter-process communication packet creation 【发布时间】:2015-10-14 12:40:06 【问题描述】:我正在编写一个进程间通信协议,其中 C# 客户端调用服务器进程中的 API,这些 API 将使用不同的语言(Java、C、C++ 等)编写。 两个进程在同一台机器上运行,通信层本身不是问题(目前我使用的是套接字,因为它被大多数语言支持,但以后可能会使用共享内存) 总共大约有 180 个 API,当然每个 API 都有自己的一组不同类型的参数。由于服务器可以用任何语言编写,我将所有参数转换为字节数组,将其放入带有 API 标识符的数据包中,然后将其发送到其他进程,在该进程中将根据 API 标识符对其进行解码。从服务器进程返回的数据将以相同的方式格式化。
我正在寻找的是最快的方法(最好是单个函数),它采用可变数量的不同类型参数并将它们转换为字节数组。目前,我正在使用 BitConverter 类将每个参数转换为字节数组并将所有数组连接成一个。除了字符串之外没有引用类型参数,它将被转换为一个字节数组,其中前 2 个字节包含字符串长度。我可以控制客户端和服务器,因此每个人都知道数据包中期望的参数顺序(基于 API ID)以及每个参数的大小。
如果有其他方法可以做到这一点,或者如何使用单个函数来做到这一点,例如:
byte[] toByteArray (variable-number of different-type parameters…)
请告诉我。性能是一个问题,因为 API 调用的频率非常高。
【问题讨论】:
【参考方案1】:我认为您应该尝试 Google 的协议缓冲区:https://developers.google.com/protocol-buffers/
Protobuf 是语言中立的。因此,您可以定义自己的结构,然后为 Java、C#、C++ 等生成特定代码。
【讨论】:
【参考方案2】:我选择使用以下代码。最初担心使用参数和装箱/拆箱对性能的影响,但经过一些分析后发现它可以忽略不计。有兴趣的朋友可以看看。
public static int ToByteArray (byte[] bytes, int Offs, params object[] args)
int CurrIdx = Offs;
for (int i=0; i<args.Length; i++)
object obj = args[i];
if (obj is int)
int x = (int) obj;
bytes[CurrIdx++] = (byte)(x & 0xff);
bytes[CurrIdx++] = (byte)((x >> 8) & 0xff);
bytes[CurrIdx++] = (byte)((x >> 16) & 0xff);
bytes[CurrIdx++] = (byte)((x >> 24) & 0xff);
else if (obj is double)
double x = (double)obj;
System.Buffer.BlockCopy(BitConverter.GetBytes(x), 0, bytes, CurrIdx, sizeof(double));
CurrIdx += sizeof(double);
else if (obj is string)
string x = (string)obj;
int ByteLen = x.Length * sizeof(char);
bytes[CurrIdx++] = (byte)(x.Length & 0xff);
bytes[CurrIdx++] = (byte)((x.Length >> 8) & 0xff);
System.Buffer.BlockCopy(x.ToCharArray(), 0, bytes, CurrIdx, ByteLen);
CurrIdx += ByteLen;
return (CurrIdx - Offs);
【讨论】:
以上是关于进程间通信包创建的主要内容,如果未能解决你的问题,请参考以下文章