How to do it...

In this recipe, we are going to create two applications: a sender and a receiver. The sender will write data for the receiver, thus encoding them in a platform-independent way. Follow these steps to do so:

  1. In your working directory, that is, ~/testcreate a subdirectory called enconv.
  2. Use your favorite text editor to create and edit a file called sender.cpp in the enconv subdirectory. Include the required header files, as follows:
#include <stdexcept>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
  1. Then, define a function that writes data to the file descriptor:
void WriteData(int fd, const void* ptr, size_t size) {
size_t offset =0;
while (size) {
const char *buffer = (const char*)ptr + offset;
int written = write(fd, buffer, size);
if (written < 0) {
throw std::runtime_error("Can not write to file");
}
offset += written;
size -= written;
}
}
  1. Now, we need to define a function that formats and writes messages, along with the main function that invokes it:
void WriteMessage(int fd, const char* str) {
uint32_t size = strlen(str);
uint32_t encoded_size = htonl(size);
WriteData(fd, &encoded_size, sizeof(encoded_size));
WriteData(fd, str, size);
}

int main(int argc, char** argv) {
int fd = open("envconv.data",
O_WRONLY|O_APPEND|O_CREAT, 0666);
for (int i = 1; i < argc; i++) {
WriteMessage(fd, argv[i]);
}
}
  1. Similarly, create a file called receiver.cpp with the same set of includes:
#include <stdexcept>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
  1. Add the following code, which reads data from a file descriptor:
void ReadData(int fd, void* ptr, size_t size) {
size_t offset =0;
while (size) {
char *buffer = (char*)ptr + offset;
int received = read(fd, buffer, size);
if (received < 0) {
throw std::runtime_error("Can not read from file");
} else if (received == 0) {
throw std::runtime_error("No more data");
}
offset += received;
size -= received;
}
}
  1. Now, define a function that will read messages, along with the main function that invokes it:
std::string ReadMessage(int fd) {
uint32_t encoded_size = 0;
ReadData(fd, &encoded_size, sizeof(encoded_size));
uint32_t size = ntohl(encoded_size);
auto data = std::make_unique<char[]>(size);
ReadData(fd, data.get(), size);
return std::string(data.get(), size);
}

int main(void) {
int fd = open("envconv.data", O_RDONLY, 0666);
while(true) {
try {
auto s = ReadMessage(fd);
std::cout << "Read: " << s << std::endl;
} catch(const std::runtime_error& e) {
std::cout << e.what() << std::endl;
break;
}
}
}
  1. Create a file called CMakeLists.txt in the loop subdirectory with the following content:
cmake_minimum_required(VERSION 3.5.1)
project(conv)
add_executable(sender sender.cpp)
add_executable(receiver receiver.cpp)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

SET(CMAKE_CXX_FLAGS "--std=c++14")
set(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabi-g++)

  1. Build the application and copy the two resulting executable binaries, sender and receiver, to the target system. Use the recipes from Chapter 2Setting Up the Environment, to do so.
  2. Switch to the target system's Terminal. Log in using your user credentials, if needed.
  1. Run the sender binary and pass two command-line arguments: Hello and Worlds. This won't generate any output.
  2. Then, run the receiver.
  3. Now, check the content of the file for both the sender and receiver that were used for data exchange. It will be in binary format, so we need to use the xxd tool to convert it into hexadecimal format:
$ xxd envconv.data 
0000000: 0000 0005 4865 6c6c 6f00 0000 0557 6f72 ....Hello....Wor
0000010: 6c64 ld
  1. The file contains two strings, hello and world, prepended by their sizes. The size fields are always stored in big-endian byte order, independent of the architecture. This allows the sender and the receiver to be run on two different machines with different endianness.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.23.101.60