2009-07-21 142 views
4

我发现自己经常遇到一种情况,那里有一组需要通过TCP/IP连接发送的消息。我从来没有找到一个好的解决方案来设计消息类。我想有一个消息基类,其中所有消息都来自它。由于每条消息都有不同的字段,这将允许我通过成员变量或方法访问字段。类似...通过TCP/IP连接流式传输

class message_base 
{ 
    public: 
    message_base(); 
    virtual ~message_base(); 

    unsigned int type; 
}; 

class message_control : public message_base 
{ 
    public: 
    message_control(); 
    virtual ~message_control(); 

    unsigned int action; 
}; 

这样我就可以创建一个message_control并访问操作成员以分配和读取。我也可以在不写太多代码的情况下传递消息。

当我需要发送消息时出现问题。如果我覆盖运营商< <和operator >>,那么我可以一次发送一个变量的消息。该解决方案的问题在于,如此多的调用来发送数据,上下文切换将会冲击处理器。此外,流式运算符结束了套接字类,而不是在我更喜欢它的消息类中。

socket& socket::operator<<(message_control& message) 
{ 
    sock << type; 
    sock << action; 
} 

如果我在一个缓冲区将数据打包,我跑不掉从C++多为C的境界,并发现自己制作大量使用指针和等。而且,修改代码很困难且容易出错。而且,流操作符仍然在套接字类中,而不是消息类。

socket& socket::operator<<(message_control& message) 
{ 
    byte* buffer = new byte[sizeof(message.type) + sizeof(message.action)]; 

    memcpy(buffer, message.type, sizeof(message.type)); 
    memcpy(buffer + sizeof(message.type), message.action, sizeof(message.action)); 

    sock.send(buffer); 
} 

我最后一次尝试使用中间类来处理打包和解包缓冲区中的成员。消息可以实现运算符< <和运算符>>到缓冲区类,然后将缓冲区类发送到套接字。这有效,但感觉不对。

class socket 
{ 
    public: 
    socket(); 
    ~socket(); 

    socket& operator<<(buffer& buff); 
}; 

class buffer 
{ 
    public: 
    buffer() {m_buffer = new byte[initial_size];} 
    ~buffer() {delete [] m_buffer;} 

    buffer& operator<<(unsigned int value); 

    private: 
    byte* m_buffer; 
}; 

void message_control::serialize(buffer& buff) 
{ 
    buff << type; 
    buff << action; 
} 

我不禁感到这是一个优雅的解决方案。我找不到任何符合我想要完成的设计模式。有没有人遇到过这个问题,并提出一个不会让你觉得用旧指针和字节数组更好的设计方案?

更新

我失败了,我,我最常处理的很好定义有线协议原职提。这就是为什么我通常需要推出我自己的解决方案,并且不能使用任何可用于通过网络连接进行消息传递的精彩工具包。

+0

你有没有看使用ACE? – Alan 2009-07-21 23:32:28

回答

1

“这个解决方案的问题是,有这么多的调用来发送数据,上下文切换会冲击处理器。而且,流操作符结束了套接字类,而不是在我更喜欢它的消息类中住“。

第二个问题的解决方案是将operator<<定义为包含消息类的名称空间中的非成员函数,而不是作为套接字类的成员函数。 ADL会找到它。

第一个问题的解决方案是缓冲您的进程中的数据,然后在每条消息的末尾刷新。如果Nagle缓冲不阻止上下文切换,那么您可能可以通过与套接字混淆来实现这一点,我不知道。然而,你当然可以做的是在发送更多的C++方式之前准备每条消息。更换:

sock << type; 
sock << action; 

有:

stringstream ss; 
ss << type; 
ss << action; 
sock << ss.str();