封装数据(网络编程)

时间:2011-03-28 15:19:51

标签: c++ serialization network-programming encapsulation

我已经阅读了BG的网络编程简介,但有一个主题仍然值得怀疑:数据封装 基本上我创建了一个包含数据长度和消息的结构。例如:

struct Data
{  
    int length;  
    std::string message;  
}

我该怎么发送?使用send()函数,我只能发送char *类型的变量 另外,当我发送它时,在服务器端,我应该创建一个由封装指定的长度的动态缓冲区并将消息打包到它中吗?

2 个答案:

答案 0 :(得分:2)

C ++中的常见方法是提供可以将自定义类型序列化为“流”对象的函数,然后提供一种方法来获取指向流中累积的数据块开头的指针。 / p>

一个简单的例子是std :: ostringstream,您可以使用它将数据序列化为流,然后获取指向构造字符串的指针:

int i = 13;
std::string message = "Hi";
std::ostringstream stream;
stream << i << message;

cout << stream.str() << endl; // prints "13Hi";

您可以通过提供Data<<运算符的适当重载来为>>类型执行相同操作,如下所示:

std::ostringstream &operator<<( std::ostringstream &stream, const Data &v ) {
  return stream << v.length << v.message;
}

std::ostringstream &operator>>( std::ostringstream &stream, Data &v ) {
  return stream >> v.length; >> v.message;
}

使用这些功能,您可以这样做:

Data myData = { 13, "Hello" };

std::ostringstream stream;
stream << myData;

const std::string serializedData = stream.str();
send( .., serializedData.c_str(), serializedData.size() + 1, .. );

在接收大小上,您可以将数据读入缓冲区,然后使用std::istringstream对象再次提取数据:

const char receivedData[ 1024 ];
// fill receivedData array using recv()

std::string s = receivedData;
std::istringstream stream( s );
Data myData;
stream >> myData;

您可能需要稍微缓冲接收到的数据,直到从流中读取成功为止。

答案 1 :(得分:0)

Send()接受char *以允许以一个字节的倍数发送任何二进制数据。你有没有尝试过铸造char *?

在接收端,你必须解压缩前几个字节以发现长度。当然,这种方法假设发送方和接收方使用相同的长度。您还应该注意发送给编译器的打包参数。