通过TCP/IP连接流式传输
我发现自己经常遇到一种情况,那里有一组需要通过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;
}
我不禁感到这是一个优雅的解决方案。我找不到任何符合我想要完成的设计模式。有没有人遇到过这个问题,并提出一个不会让你觉得用旧指针和字节数组更好的设计方案?
更新
我失败了,我,我最常处理的很好定义有线协议原职提。这就是为什么我通常需要推出我自己的解决方案,并且不能使用任何可用于通过网络连接进行消息传递的精彩工具包。
“这个解决方案的问题是,有这么多的调用来发送数据,上下文切换会冲击处理器。而且,流操作符结束了套接字类,而不是在我更喜欢它的消息类中住“。
第二个问题的解决方案是将operator<<
定义为包含消息类的名称空间中的非成员函数,而不是作为套接字类的成员函数。 ADL会找到它。
第一个问题的解决方案是缓冲您的进程中的数据,然后在每条消息的末尾刷新。如果Nagle缓冲不阻止上下文切换,那么您可能可以通过与套接字混淆来实现这一点,我不知道。然而,你当然可以做的是在发送更多的C++方式之前准备每条消息。更换:
sock << type;
sock << action;
有:
stringstream ss;
ss << type;
ss << action;
sock << ss.str();
你有没有看使用ACE? – Alan 2009-07-21 23:32:28