Приложение для синхронного чата с использованием C ++ boost :: asio

Опубликовано: 29 Декабря, 2021

Библиотека Boost состоит из asio, которая представляет собой бесплатную кроссплатформенную библиотеку C ++ для сетевого и низкоуровневого программирования ввода-вывода, которая обеспечивает согласованную асинхронную модель с использованием современного подхода C ++. Эта статья поможет разработать приложение для синхронного чата клиент-сервер с использованием boost :: asio . Мы явно упоминаем «синхронный», потому что в синхронной модели один из наших клиентов или серверов должен ждать другого.
Серверное приложение: Ниже приведены различные шаги для создания серверного приложения:

  • Импорт boost / asio.hpp (Версия: 1.65.1.0)
 #include <boost / asio.hpp>
  • Создание объекта io_service (для сервера), который является обязательным для использования boost :: asio.
 boost :: asio :: io_service io_service_object;
  • Создание объекта-приемника, передача объекта io_service и конечной точки соединения, то есть IPv4 и номера порта 9999 (протокол IPv6 также поддерживается в boost :: asio, также обратите внимание, что порты 0 - 1233 зарезервированы).
 boost :: asio :: ip :: tcp :: acceptor 
  acceptor_object (
    io_service_object, 
    tcp :: endpoint (boost :: asio :: ip :: tcp :: v4 (), 
                  9999));
  • Создание объекта tcp :: socket для нашего сервера.
 boost :: asio :: ip :: tcp :: socket_object (io_service_object)
  • Вызов метода accept объекта-приемника для установления соединения.
 acceptor_server.accept (server_socket);
  • Метод read_until () извлекает сообщение из буфера, в котором хранятся данные во время связи. Здесь мы используем « n» в качестве разделителя вывода, что означает, что мы будем продолжать читать данные из буфера, пока не встретим « n» и не сохраним их.
 // Создаем буфер для хранения
boost :: asio :: streambuf buf;

boost :: asio :: read_until (сокет, buf, " n");
строковые данные = boost :: asio :: buffer_cast (buf.data ());
  • Метод write () записывает данные в буфер, принимая объект сокета и сообщение в качестве параметра.
 boost :: asio :: write (
  разъем, 
  boost :: asio :: buffer (сообщение + " n"));

Клиентское приложение: Ниже приведены различные шаги для создания клиентского приложения:

  • Импортируем boost / asio.hpp.
 #include <boost / asio.hpp>
  • Создание объекта io_service для клиента.
 boost :: asio :: io_service io_service_object;
  • Создание объекта tcp :: socket для клиента.
 boost :: asio :: ip :: tcp :: socket
  socket_object (io_service_object)
  • Вызов метода подключения объекта сокета для инициирования соединения с сервером с использованием localhost (IP 127.0.0.1) и подключения к тому же порту 9999.
 client_socket.connect (
  tcp :: endpoint (
    адрес :: from_string ("127.0.0.1"), 
    9999));
  • read_until () и write () останутся такими же для нашего клиентского приложения, как и на стороне сервера.

Ниже представлена реализация описанного выше подхода: Программа:

server.cpp
 // Server-side Synchronous Chatting Application // using C++ boost::asio #include <boost/asio.hpp> #include <iostream> using namespace std; using namespace boost::asio; using namespace boost::asio::ip; // Driver program for receiving data from buffer string getData(tcp::socket& socket) { streambuf buf; read_until(socket, buf, "
"); string data = buffer_cast<const char*>(buf.data()); return data; } // Driver program to send data void sendData(tcp::socket& socket, const string& message) { write(socket, buffer(message + "
")); } int main(int argc, char* argv[]) { io_service io_service; // Listening for any new incomming connection // at port 9999 with IPv4 protocol tcp::acceptor acceptor_server( io_service, tcp::endpoint(tcp::v4(), 9999)); // Creating socket object tcp::socket server_socket(io_service); // waiting for connection acceptor_server.accept(server_socket); // Reading username string u_name = getData(server_socket); // Removing "
" from the username u_name.pop_back(); // Replying with default message to initiate chat string response, reply; reply = "Hello " + u_name + "!"; cout << "Server: " << reply << endl; sendData(server_socket, reply); while (true) { // Fetching response response = getData(server_socket); // Popping last character "
" response.pop_back(); // Validating if the connection has to be closed if (response == "exit") { cout << u_name << " left!" << endl; break; } cout << u_name << ": " << response << endl; // Reading new message from input stream cout << "Server" << ": "; getline(cin, reply); sendData(server_socket, reply); if (reply == "exit") break; } return 0; }

client.cpp

 // Client-side Synchronous Chatting Application // using C++ boost::asio #include <boost/asio.hpp> #include <iostream> using namespace std; using namespace boost::asio; using namespace boost::asio::ip; string getData(tcp::socket& socket) { streambuf buf; read_until(socket, buf, "
"); string data = buffer_cast<const char*>(buf.data()); return data; } void sendData(tcp::socket& socket, const string& message) { write(socket, buffer(message + "
")); } int main(int argc, char* argv[]) { io_service io_service; // socket creation ip::tcp::socket client_socket(io_service); client_socket .connect( tcp::endpoint( address::from_string("127.0.0.1"), 9999)); // Getting username from user cout << "Enter your name: "; string u_name, reply, response; getline(cin, u_name); // Sending username to another end // to initiate the conversation sendData(client_socket, u_name); // Infinite loop for chit-chat while (true) { // Fetching response response = getData(client_socket); // Popping last character "
" response.pop_back(); // Validating if the connection has to be closed if (response == "exit") { cout << "Connection terminated" << endl; break; } cout << "Server: " << response << endl; // Reading new message from input stream cout << u_name << ": "; getline(cin, reply); sendData(client_socket, reply); if (reply == "exit") break; } return 0; }

C++