-1

Any recommendations on how to encode data to send over a socket?

Example

struct {
    int id,
    std::string name,
    std::string address
}

I have this currently:

std::string s;
client_type client = { INVALID_SOCKET, -1, "" };
send(client.socket, s.c_str(), strlen(s.c_str()), 0);

I can send a string. What would be the best way to send the above information to the server?

Bradmage
  • 1,233
  • 1
  • 15
  • 41
  • 2
    Transform your data into something machine readable. On of the better text base formats is JSON. – Arne Fischer Aug 10 '19 at 10:41
  • Duplicate: https://stackoverflow.com/questions/57440928/c-socket-packet-format – πάντα ῥεῖ Aug 10 '19 at 10:51
  • @πάνταῥεῖ Obviously, they are both by me, worded differently and got different answers. If not I would not have gotten an answer. – Bradmage Aug 10 '19 at 10:54
  • @Bradmage Well, learn how to distinguish socket configuration and actions from payload sent over it. That's the essence. I am not well versed with PHP, but it seems that there are some levels abstracted there. – πάντα ῥεῖ Aug 10 '19 at 11:24
  • @πάνταῥεῖ Can you elaborate on your comment? I didn't mention PHP in this question, or socket config. I am literally asking how to properly send a payload of data. send() requires a string so we need to encode and decode that data if it is more than a basic string. – Bradmage Aug 10 '19 at 11:36
  • @ArneFischer Your comment should almost be an answer. JSON is where I would go if I don't get an answer, I kind of thought C++ would have a mechanism for encoding data to send over a socket. It's not like sending data over a network is a rare event.. – Bradmage Aug 10 '19 at 11:41
  • @Bradmage I don't think there is out of the box serialization in c++, but there is a ton of free libraries available, I can't speak to available json serializier since we wrote our own (json is pretty simple). If you need some really efficient serialization you can also have a look at protocol buffer: https://developers.google.com/protocol-buffers/docs/cpptutorial – Arne Fischer Aug 10 '19 at 11:44
  • 1
    @ArneFischer Thanks for a decent answer, there are way too many hates on SO and C++. That is what I figured, In this project I'm trying to use as much native as possible for learning purposes. It's been a long time since I coded anything but web apps. – Bradmage Aug 10 '19 at 11:53

1 Answers1

1

Use a serialization library and convert your data into one of the known data formats via that library. I, for instance, use cereal (check the link for an example) library to serialize my data into json format. This is a good list of C++ serialization libraries. Choose the format which suits best for you and then choose a library to serialize and de-serialize the data.

Here is an example of xml serialization with cereal for your case (edit: compiles now):

#include <cereal/archives/xml.hpp>
#include <sstream>
#include <iostream>


struct SomeData{
    int id;
    std::string name;
    std::string address;

    template <class Archive>
    void serialize( Archive & ar )
    {
        ar( id, name, address );
    }
};

int main()
{
    std::stringstream ss;

    // this block is used to make sure the destrcutor of archive is called
    // which flushes the output into string stream.
    {
        cereal::XMLOutputArchive archive( ss );

        SomeData myData{4, "name", "address"};
        archive( myData );
    }
    std::string s = ss.str();

    // test output 
    std::cout << s << std::endl;

    // send data
    send(client.socket, s.c_str(), s.length(), 0);
    return 0;
}

This is the output:

<?xml version="1.0" encoding="utf-8"?>
<cereal>
    <value0>
        <value0>4</value0>
        <value1>name</value1>
        <value2>address</value2>
    </value0>
</cereal>    
seleciii44
  • 1,529
  • 3
  • 13
  • 26
  • omg, someone actually answered, with what I was asking, and got a down vote with no explanation! If I don't get a final answer your getting the accepted answer. – Bradmage Aug 10 '19 at 11:13
  • 1
    @πάνταῥεῖ No you miss understand, this answer got a down vote almost straight away. As for my question, it is pretty straight forward, how do I encode an array of data to send over a socket. It can't get much simpler than that. – Bradmage Aug 10 '19 at 11:31
  • @πάνταῥεῖ as Bradmage stated I don't see a reason to downvote this answer without any explanation. If there really is a reason, I would fix my fault whatever it is. – seleciii44 Aug 10 '19 at 12:08
  • @bra: This *is* a pretty questionable answer. XML is probably the worst you can opt for, if you plan to efficiently transport, and re-assemble the serialized stream into structured objects. [Protocol Buffers](https://developers.google.com/protocol-buffers/) is probably a way more complete and useful library. – IInspectable Aug 10 '19 at 12:10
  • @IInspectable I''ve picked xml just for an example, it only requires two lines to change it into json serializer. – seleciii44 Aug 10 '19 at 12:11
  • 1
    JSON is equally inadequate. There's just nothing that beats a binary serializer (like protobuf) in terms of efficiency and error discovery. Deserializing XML or JSON always runs a pretty complex state machine, that reads, tries to decode, checks for exactly enough, too little, or too much data, and branches from there. – IInspectable Aug 10 '19 at 12:17
  • @IInspectable I agree with you. I haven't read your first comment carefully. However, I prefer human-readable formats if efficiency is no big deal. – seleciii44 Aug 10 '19 at 12:23
  • This is for a network protocol. There is no human reader involved. This is in contrast to, say, configuration files, that are (in part) meant for human consumption. – IInspectable Aug 10 '19 at 12:28
  • @IInspectable I partially agree on you. Human readers may be involved. I know too many cases checking Wireshark to see what is flowing in the network. However, the question is not asking for selecting the best serialization format, neither I suggest the OP to use JSON or XML. You should read my answer carefully, I suggest the OP to select the format which suits best for his/her needs. The list I've shared already contains protobuf, anyway. Also, `cereal` itself can serialize into binary format. And yes probably protobuf is the best for many cases. Thus, I don't see a reason to keep arguing. – seleciii44 Aug 10 '19 at 12:49
  • If you need to dissect binary protobuf packets in Wireshark, there are *loads* of [3rd-party tools](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md) available. Regardless, this Q&A was closed as being primarily opinion-based, and both this answer as well as the comments following it seem to confirm this. – IInspectable Aug 10 '19 at 13:07