Hey Ninjas! We have studied various protocols. Protocols are the set of rules that are required for secure and efficient data transfer. You must have heard about HTTP, SMTP, or FTP. These are the most commonly used internet protocols. These protocols are line-based protocols. If you are unfamiliar with line-based protocols, Don’t worry, we will be covering this.
In this article, we will learn about line-based protocols and what line-based operations are. The functions like async_read_until, is_match_condition, read_until, etc., will also be covered. So let’s start by first learning Asio.
What is Asio?
Asio, asynchronous input-output, is an open-source, cross-platform C++ library. It is designed for input, output, and networking. It was developed in 2003 by Christopher M. Kohlhoff and was released under Boost Software License. It provides an asynchronous model to the developers using a modern approach of C++. It is supported by a huge number of platforms like Windows, macOS, Linux, etc.
Before moving forward, let us first see what Internet Protocols are.
The Internet Protocol (IP) is a set of rules which are used for routing packets across various networks. It is also used for providing addresses to the packets of data so that they can be identified correctly. Examples of IP are- HTTP (Hyper Text Transfer Protocol), FTP (File Transfer Protocol), TCP (Transmission Control Protocol), etc.
Whenever we use the internet to visit any website or communicate with another device, then these protocols are used to secure the data. Upon the arrival of the packets to their destination, they are treated in different ways according to the transport protocol, which is used in combination with IP.
Line-Based Operations
Line-Based operations are the actions that are performed on line-based protocols. Let’s first see what line-based protocols are:
💠 The most used internet protocols like HTTP, FTP, and SMTP are line-based protocols.
💠 They are called line-based because they are delimited by the character sequence “\r\n.”
💠 Simply, they use whitespace and syntax to format the elements of the fields like timestamp, tag set, single data point, fieldset, etc.
💠 Asio consists of the functions read_until() and async_read_until() to implement the line-based protocols and other protocols using delimiters.
Let’s look at the functions used to implement the line-based protocols in detail:
read_until
The read_until() consists of operations that are used to read data into a streambuf or a dynamic buffer sequence until it matches a regular expression or contains delimiters or a function object matches. The streambuf is an input/output buffer that is used along with I/O streams.
The requirements for this function are the header file asio/read_until.hpp and the convenience header asio.hpp.
async_read_until
The async_read_until() consists of an asynchronous operation that is used to perform the same operation as read_until(), that is,to read data into a streambuf or a dynamic buffer sequence until it matches a regular expression or contains delimiters or a function object matches.
The requirements for this function are also the same, that is, the header file asio/read_until.hpp and the convenience header asio.hpp. The streambuf is used in both read_until and async_read_until. Let’s discuss in detail what streambuf refers to.
streambuf
The streambuf is a typedef to use basic_streambuf, which is an automatically resizable buffer class. It is used to match the streambuf’s output and input sequences with the character arrays. These character arrays are the basic_streambuf object which can be directly accessed by the array elements and can be used effectively with I/O operations. The following is the syntax:
typedef basic_streambuf streambuf;
Member Functions
The following are its member functions with their syntax and their description.
is_match_condition
The is_match_condition type trait is used to find if the type can be used as a match condition function with read_until and async_read_until. We need to include the header asio.read_until.hpp to use the same.
We can create the is_match_condition by writing the following statement.
template<
typename T>
struct is_match_condition
The following is its data member, along with the syntax.
Let’s see an example to implement these.
Implementation of Line-Based Operation
We need to use Socket programming in order to use the function read_until. We have written both server-side and client-side codes for the same. Let’s understand both.
Server-Side Implementation
First, we need to accept the request coming from the client for a new connection, so we have used tcp::acceptorfor the same. Now we need a streambuf class that represents a buffer of data to read data as a stream. We are storing the data in a string and displaying it. After reading, we performed a write operation to send the response to the client.
Code
#include <iostream>
#include <asio.hpp>
using asio::ip::tcp;
int main() {
asio::io_service io_service;
// Listen for new connection
tcp::acceptor acceptor_(io_service, tcp::endpoint(tcp::v4(), 8080));
//socket creation
tcp::socket socket_(io_service);
// Waiting for connection
acceptor_.accept(socket_);
// Read operation
asio::streambuf buf;
asio::read_until(socket_, buf, "\n");
std::string message = asio::buffer_cast<const char*>(buf.data());
std::cout << message << std::endl;
// Write operation
const std::string msg = "Hello Ninjas! This message is sent from Server!\n";
asio::write(socket_, asio::buffer(msg));
std::cout << "Server has sent a message to the Client!" << std::endl;
return 0;
}
You can also try this code with Online C++ Compiler
In order to connect to the server, we need a socket object. The connection request is then made to the server. We have sent a message to the server using the write operation. In case of an error, we will print the error message. The streambuf is again used to read the response from the server. If there is no error, we will print the message received.
Code
#include <iostream>
#include <asio.hpp>
using asio::ip::tcp;
int main() {
asio::io_service io_service;
tcp::socket socket(io_service);
// Connect the socket
socket.connect(tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 8080));
const std::string msg = "Hello Ninjas! This message is from Client!\n";
asio::error_code error;
asio::write(socket, asio::buffer(msg), error);
if (!error) {
std::cout << "Client has sent a message to Server!" << std::endl;
}
else {
std::cout << "send failed: " << error.message() << std::endl;
}
// Getting response from server
asio::streambuf receive_buffer;
asio::read(socket, receive_buffer, asio::transfer_all(), error);
if (error && error != asio::error::eof) {
std::cout << "receive failed: " << error.message() << std::endl;
}
else {
const char* data = asio::buffer_cast<const char*>(receive_buffer.data());
std::cout << data << std::endl;
}
return 0;
}
You can also try this code with Online C++ Compiler
Asio is a cross-platform, open-source C++ library. It is an underrated C++ library designed for input, output, and networking purposes. Asio stands for asynchronous input-output. Christopher M. Kohlhoff developed Asio in 2003.
How are asynchronous operations different from synchronous operations?
The operations and programs in asynchronous operations can run in parallel, while the programs in synchronous operations will run one at a time. The asynchronous operations are non-blocking, while the synchronous operation is blocking.
How do Internet Protocols protect data on the network?
The internet protocols help to determine the correct destination and deliver the packets accordingly. It checks the data with the use of a checksum mechanism. A packet is lost or undelivered if the destination Ip is not alive.
What is the use of the Asio library?
Asio helps in doing network programming using C++ language. It allows the processing of data asynchronously by providing asynchronous I/O models.
Conclusion
This article was about Asio, which is a C++ library for networking and communication. We have discussed line-based operations in this article. We have also covered some important functions like read_until, async_read_until, etc., and class streambuf and its member functions.
You can check out our other articles if you want to dive deep into other concepts related to Asio -