简体   繁体   English

通过C ++套接字(linux)发送std :: map <int,std :: map <std :: string,double >>

[英]Sending an std::map<int, std::map<std::string, double> > over C++ socket (linux)

I am trying to send a map composed of an int and another map over TCP socket in linux. 我试图在linux中通过TCP套接字发送由int和另一个映射组成的映射。

the map is of the form 地图是形式

map<int, map<string, double>>

Following this SO link i tried to do 按照这个SO链接我试着做

unsigned char* mybytemap =  reinterpret_cast<unsigned char*>(&my_map);

then to send the buffer i used write() function as follows: 然后发送缓冲区我用write()函数如下:

int size = sizeof(mybytemap);
char temp[10];
sprintf(temp, "%d", size);
write(sockfd, temp, strlen(temp));     //send the size for the client
write(sockfd, mybytemap, sizeof(mybytemap));

On the client side: 在客户端:

char temp[10];
n  = read(sockfd, temp, 10);
size = stoi(temp);    //Got Size Of buffer

unsigned char * buf;
if(size != 0)
{
    buf = new unsigned char[size];
    int current=0;
    while(current<size)
    {
        n = read(sockfd,(unsigned char*)(buf)+current, min(1024,size-current));
        if (n <= 0)
        {
            cout<<"ERROR reading from socket when receiving"<<endl;
            break;
        }
        current+=n;
    }
}

map<int, map<string, double>> *test = reinterpret_cast< map<int, map<string, double>>* > (buf);

vector<int> ks;
for(map<int, map<string, double>>::iterator it = test->begin(); it != test->end(); ++it)
{
    ks.push_back(it->first);
    cout<<"id: "<<it->first<<endl;
}

but the Map isn't received correctly and code crashes when trying to access the data. 但是在尝试访问数据时未正确接收Map并且代码崩溃。 how to fix that? 怎么解决这个问题?

Do i need to XML the map? 我需要XML地图吗? and if so can someone guide me on how to do that? 若有,有人可以指导我如何做到这一点?

answer in link in your question is not applicable to map (map is not pod) 您的问题中的链接答案不适用于地图(地图不是pod)

general idea how you can to encode\\decode map : encode size of map and then for each key/value encode size of key, then encode key, then encode size of value, then encode value. 一般的想法如何编码\\ decode map:编码map的大小然后为每个键/值编码密钥的大小,然后编码密钥,然后编码值的大小,然后编码值。 Following code assumes you encode size_t into sizeof(size_t) bytes 以下代码假定您将size_t编码为sizeof(size_t)字节

template<class T>
std::string encode(T value){
   // data to bytes
}

template<class T> 
T decode(std::string bytes){
  // bytes to data
}

template<class K, class V>
std::string encode_map(std::map<K, V> data){
  std::string result;
  result.append(encode<size_t>(data.size()));
  for(auto iter: data){
    std::string first = encode<K>(iter.first);
    result.append(encode<size_t>( first.size() ));
    result.append(first);
    std::string second = encode<V>(iter.second);
    result.append(encode<size_t>( second.size() ));
    result.append(encode<V>(iter.second));
  }
  return result;
}

template<class K, class V>
std::map<K, V> decode_map(std::string bytes){
  size_t index = 0;
  size_t size = decode<size_t>(std::string(bytes.begin()+index, bytes.begin()+index+sizeof(size_t) ) );
  index += sizeof(size_t);
  std::map<K, V> result;
  for(size_t i = 0; i<size; i++){
    size_t next_size = decode<size_t>(std::string(bytes.begin()+index, bytes.begin()+index+sizeof(size_t) ) );
    index += sizeof(size_t);
    K key = decode<K>(std::string(bytes.begin()+index, bytes.begin()+index+next_size ) );
    index += next_size;
    next_size = decode<size_t>(std::string(bytes.begin()+index, bytes.begin()+index+sizeof(size_t) ) );
    index += sizeof(size_t);
    V value = decode<V>(std::string(bytes.begin()+index, bytes.begin()+index+next_size ) );
    index += next_size;
    result[key] = value;
  }
  return result;
}

As recommended, you need to perform so-called serialization . 按照建议,您需要执行所谓的序列化 You can employ Boost.Serialization as a serialization library. 您可以将Boost.Serialization用作序列化库。 It can handle all STL types. 它可以处理所有STL类型。 An illustrative example: 一个说明性示例:

std::map<int, std::map<std::string, double>> m1;
// ... (fill m1)

// serialize into a buffer (string):
std::string buffer;
boost::iostreams::back_insert_device<std::string> inserter(buffer);
boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>> ostr(inserter);
boost::archive::binary_oarchive oa(ostr);
oa << m1;
ostr.flush();

// ... (here you can send the contents of buffer as plain bytes-chars via socket)

// deserialize into new map:
boost::iostreams::basic_array_source<char> device(buffer.data(), buffer.size());
boost::iostreams::stream<boost::iostreams::basic_array_source<char>> istr(device);
boost::archive::binary_iarchive ia(istr);
std::map<int, std::map<std::string, double>> m2;
ia >> m2;

Full live demo (with all headers): https://wandbox.org/permlink/NyZeVTrFI0p8RcmY 完整的现场演示(包括所有标题): https//wandbox.org/permlink/NyZeVTrFI0p8RcmY

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c++:转换std::map<std::string, double> 到 std::map<std::string_view, double></std::string_view,></std::string,> - c++ : convert std::map<std::string, double> to std::map<std::string_view, double> 是等价于 std::map 的 trie<std::string, int> 在 C++ 中?</std::string,> - Is a trie equivalent to std::map<std::string, int> in C++? c++ 标准::map<std::string, int> 与 std::string_view 一起使用</std::string,> - c++ std::map<std::string, int> use at with std::string_view 如何遍历集合的映射 (std::map <std::set< char> , int &gt;) 在 C++ 中? - How to iterate over a map of set (std::map<std::set< char>, int >) in C++? C ++ std :: map和std :: pair <int, int> 作为关键 - C++ std::map and std::pair<int, int> as Key 将数据插入std :: map <std::string, int> mymap来自两个不同的数据结构并通过套接字发送 - Insert data into std::map <std::string, int> mymap from two different data structure and sending it via socket 如何遍历集合的映射 (std::map <string,std::set< string> &gt;) 在 C++ 中? - How to iterate over a map of set (std::map<string,std::set< string> >) in C++? 如何使用std :: map检索std :: vector <int> 在C ++中? - How to use std::map to retrive a std::vector<int> in c++? C++ std::map<std::string, int> 获取键以特定字符串开头的值 - C++ std::map<std::string, int> get values whose key starts with a particular string C ++循环std :: vector <std::map<std::string, std::string> &gt; - c++ loop std::vector<std::map<std::string, std::string> >
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM