进程间通信包创建

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);
    

【讨论】:

以上是关于进程间通信包创建的主要内容,如果未能解决你的问题,请参考以下文章

进程间通信的4种方式

Linux进程间通信

Linux进程间通信

Linux进程间通信

Linux进程间通信

Linux进程间通信