如何在C ++(序列化问题)中从客户端向服务器发送struct over struct结构列表?

时间:2014-06-06 18:51:02

标签: c++ c sockets struct client-server

我有两个结构,第一个被定义为第二个结构中的列表:

struct SType{
  int Num;
  char Word[20];
  char sugg[20];
};


struct DataPktType
{
    list<SType> MyList;
    char filename[MAX_SIZE];
    int numslaves;
};

我知道有序列化的升级和谷歌库,但我想通过一个特殊的服务器发送这些数据,不允许安装升级等。
所以我必须手动完成。我在本网站上看到并测试了一个简单的答案,手动序列化和反序列化https://stackoverflow.com/a/20838004/1679519。正如我测试的那样,它的结构很好。但是,它是一个简单的结构,正如你所看到的,我在第二个结构中有一个列表。列表有不同的时间大小。
我很感激,如果有人可以展示一些例子或提示。目前我以这种方式通过套接字发送结构,导致分段错误!

// Write and read a message to/from the server 
write(Sockfd, (char*)&DataPkt, sizeof(DataPktType));
read(Sockfd, (char*)&recDataPkt, sizeof(DataPktType));

1 个答案:

答案 0 :(得分:0)

我'手动'完成了类似于我怀疑你想做的事情。

对于非简单类型(DataPktType),您可能会考虑以下原始大纲(如果只是为了帮助您入门)。

首先,我向所有需要参与的类添加了2个虚拟方法 - 在我的情况下,我们将它们称为存储和恢复。这些方法只处理自己类的数据属性。

在某种意义上,

restore()是store()的反转。

struct SType{
  int Num;
  char Word[20];
  char sugg[20];

  virtual void store(ostream& os);
  virtual void restore(istream& is);
};


struct DataPktType
{
  list<SType> MyList;
  char filename[MAX_SIZE];
  int numslaves;

  virtual void store(ostream& os);
  virtual void restore(istream& is);
};

因此,DataPktType.store()可能会将每个POD数据属性传输到ostream:

DataPktType::store(ostream& os)
{
   os << MyList.size(); // gotta know how many to extract later

   for (auto it = myList.begin(); myList.end(); it++)
   {
      it->store(os); // tell the SType to store itself at this point in the stream
   }

   os << filename;
   os << numslaves;
}

然后,'逆'可能类似于

DataPktType::restore(istream& is)
{
   size_t listSize = 0;
   is >> listSize;  
   // input error checks

   for(size_t i=0; i<listSize; ++i)
   {
      SType listItem;

      listItem.restore(is); // assumes the list item contents are 'next' in the file

      MyList.push_back(listItem); // I don't use std::list often, 
      // there seems to be several choices for adding to a list
   }

   is >> filename;
   is >> numslaves;
}

这些是我认为你需要做的事情。

请注意,没有指针进入流中。

请注意,对称性并不完美,但您必须弄清楚如何处理每个操作。

在我的努力中,我相信我在路上添加了一些简单的检查......

此外,我的团队使用文本进行第一次实施。作为人类,调试起来会容易得多,您可以使用编辑器调试“对称性”问题。

此外,您可能会发现文本i / o性能足够,因此只需将其保留为文本。

我们有一些紧迫的截止日期,最终选择了二进制i / o。但是我们保持文本i / o只是为了测试。

祝你好运。

PS - 我们最终为存储/恢复的内容添加了一个“版本”编号,以支持项目代码演变过程中的结构更改。

相关问题