C / C ++中的实现通信协议

时间:2011-02-04 15:12:05

标签: c++ c communication-protocol

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

我将使用c / c ++,我可以自由使用使用库(BSD / BOOST / Apache)但不使用GPL。我已广泛使用C ++,因此使用C ++的功能不是问题。

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

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

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

我不需要担心连接管理。我们可以假设连接已经建立,协议确实是数据交换,其中协议消息已在规范中明确定义

3 个答案:

答案 0 :(得分:10)

从界面和消息开始。

声明允许对等方交换消息的会话接口。使用简单类型将消息声明为C ++结构,如int,double,std :: string和std :: vectors。例如:

// 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)实现所需的逻辑实现消息的接口和序列化。

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

答案 1 :(得分:4)

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

答案 2 :(得分:3)

查看Google Protocol Buffers

来自说明:

  

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

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

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

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

您可能还想特别查看Linux Device Driverschapter 10。查看关于Bottom和Top Halves的部分。