I want to send the data in JSON over sockets in a server-client application written in C.
I am using json-c / libjson library for handling JSON data
To use TCP socket messages you have the client and server learn how to interpret the messages.
HTTP, for example, uses the 2 characters \r\n as end of message Another alternative option is to send the size of the message before the message.
Here's a solution that does that using the JSON Jansson library. It adds the size as a sequence of characters (e.g "123", is later parsed as integer 123), adding the character "#" as end of size header then the JSON text representation of the JSON object (as defined by the Jansson library)
size_t socket_t::write(json_t *json)
{
char *buf_json = NULL;
std::string buf_send;
size_t size_json;
//get char* from json_t
buf_json = json_dumps(json, JSON_PRESERVE_ORDER);
size_json = strlen(buf_json);
//construct send buffer, adding a header with size in bytes of JSON and # terminator
buf_send = std::to_string(static_cast(size_json));
buf_send += "#";
buf_send += std::string(buf_json);
this->write(buf_send.data(), buf_send.size());
free(buf_json);
return buf_send.size();
}
The reading is done with
json_t * socket_t::read()
{
int recv_size; // size in bytes received or -1 on error
const int size_buf = 20;
char buf[size_buf];
//peek header
if ((recv_size = recv(m_socket, buf, size_buf, MSG_PEEK)) == -1)
{
std::cout << "recv error: " << strerror(errno) << std::endl;
}
//get size of JSON message
std::string str(buf);
size_t pos = str.find("#");
std::string str_header(str.substr(0, pos));
//parse header
if ((recv_size = recv(m_socket, buf, str_header.size() + 1, 0)) == -1)
{
std::cout << "recv error: " << strerror(errno) << std::endl;
}
//sanity check
buf[recv_size - 1] = '\0';
assert(str_header.compare(buf) == 0);
size_t size_json = static_cast(std::stoull(str_header));
std::string str_buf = read_all(size_json);
//terminate buffer with size
std::string str_json = str_buf.substr(0, size_json);
//construct JSON
json_error_t *err = NULL;
json_t *json = json_loadb(str_json.data(), str_json.size(), JSON_PRESERVE_ORDER, err);
return json;
}
This is implemented in
https://github.com/pedro-vicente/lib_netsockets