15

我正在开始在软件中实现一些专有的通信协议栈,但不知道从哪里开始。这是我以前从未做过的工作,我正在寻求最佳/推荐方法的资源方面的帮助。

我将使用 c/c++,我可以自由使用库(BSD/BOOST/Apache),但没有 GPL。我已经广泛使用 C++,所以使用 C++ 的特性不是问题。

协议栈共有三层,并且已经完全指定并正式验证。所以我需要做的就是用指定的语言实现和测试它。还应该提到,协议非常简单,但可以通过可靠的物理传输层在不同的设备上运行。我知道协议状态机的事件、输入、输出、副作用和行为。一般情况下,接收中断来读取从物理层接收到的消息以读取它并发送到等待设备。接收设备可以处理响应消息并将其传递给协议层以在物理层上发送出去。

任何有关参考/建议的帮助将不胜感激。如果只是为了帮助我理解如何实现它们,我愿意使用不同的语言,但我最终将不得不求助于选择的语言。

更新:我希望实现的示例协议类似于SNEP

我不需要担心连接管理。我们可以假设连接已经建立,并且协议所做的是数据交换,其中协议消息已经在规范中得到很好的定义

4

3 回答 3

11

从接口和消息开始。

声明允许对等点交换消息的会话接口。将消息声明为具有简单类型的 C++ 结构,如整数、双精度、std::string 和 std::vector。例如:

// these are your protocol messages
struct HelloRequest {
    uint32_t seq_no;
    // more stuff
};
struct HelloResponse {
    uint32_t seq_no;
    // more stuff
};

// Session callback for received messages
struct SessionReceiver {
    virtual void connected(Session*) = 0;
    virtual void receive(Session* from, HelloRequest msg) = 0;
    virtual void receive(Session* from, HelloResponse msg) = 0;
    virtual void disconnected(Session*) = 0;
};

// Session interface to send messages
struct Session {
    virtual void send(HelloRequest msg) = 0;
    virtual void send(HelloResponse msg) = 0;
};

// this connects asynchronously and then calls SessionReceiver::connected() with a newly established session
struct SessionInitiator {
    virtual void connect(SessionReceiver* cb, std::string peer) = 0;
};

// this accepts connections asynchronously and then calls SessionReceiver::connected() with a newly accepted session
struct SessionAcceptor {
    virtual void listen(SessionReceiver* cb, std::string port) = 0;
};

然后通过编码使用这些接口的业务逻辑来测试您的接口。一旦您确信接口允许您实现所需的逻辑,就可以使用您喜欢的事件驱动框架(如 libevent 或 Boost.Asio)实现接口和消息序列化。

编辑: 请注意,接口允许您进行模拟或测试实现。此外,序列化发生在接口后面的事实意味着,对于进程内对等点,您不必序列化和反序列化消息,您可以按原样传递它们。

于 2011-02-04T15:26:49.260 回答
5

Boost.ASIO在 C++ 中的异步(或同步)网络通信方面非常先进

于 2011-02-04T15:24:51.110 回答
5

看看谷歌协议缓冲区

从描述:

协议缓冲区是一种灵活、高效、自动化的结构化数据序列化机制——想想 XML,但更小、更快、更简单。您只需定义一次数据的结构化方式,然后就可以使用特殊生成的源代码轻松地将结构化数据写入和读取各种数据流,并使用各种语言。您甚至可以在不破坏针对“旧”格式编译的已部署程序的情况下更新您的数据结构。

协议缓冲区是语言和平台中立的,因此应该适合您的项目。我找不到许可证,但至少在我能找到的任何地方都没有说“GPL”。

这将帮助您处理协议。对于实际的数据传输,好吧,除非您自己编写操作系统,否则应该使用一些原语。除非您提供更多细节,否则很难提供更准确的实施帮助。例如,您使用什么沟通渠道?以太网?

但根据经验,您应该使 ISR 尽可能短。在这些类型的解决方案中,这通常意味着将数据复制到环形缓冲区。这样您就不必在 ISR 中分配内存。ISR 在复制完数据后,应该通知包的上层。如果您可以使用 DMA,请使用它。在这种情况下,甚至可以在您开始 DMA 传输之前发送通知。

您可能还想查看Linux 设备驱动程序,尤其是第 10 章。查看关于下半部分和上半部分的部分。

于 2011-02-04T17:57:44.710 回答