Aplicación de chat síncrono usando C++ boost::asio

La biblioteca Boost consta de asio , que es una biblioteca C++ gratuita y multiplataforma para programación de red y E/S de bajo nivel que proporciona un modelo asíncrono consistente utilizando un enfoque moderno de C++. Este artículo ayudará a desarrollar una aplicación de chat sincrónico cliente-servidor utilizando boost::asio . Mencionamos explícitamente «síncrono» porque en el modelo síncrono uno de nuestros clientes o servidores tiene que esperar a otro. 
Aplicación del lado del servidor: a continuación se muestran los diversos pasos para crear la aplicación del lado del servidor:
 

  • Importando boost/asio.hpp (Versión: 1.65.1.0) 
     
#include <boost/asio.hpp>
  • Creando objeto de io_service (para servidor) que es obligatorio para usar boost::asio. 
     
boost::asio::io_service io_service_object;
  • Creando el objeto del aceptador, pasando el objeto io_service y el punto final de la conexión, es decir, IPv4 y el número de puerto 9999 (el protocolo IPv6 también es compatible con boost::asio, también tenga en cuenta que los puertos 0 – 1233 están reservados). 
     
boost::asio::ip::tcp::acceptor 
  acceptor_object(
    io_service_object, 
    tcp::endpoint(boost::asio::ip::tcp::v4(), 
                  9999));
  • Creando el objeto tcp::socket para nuestro servidor. 
     
boost::asio::ip::tcp::socket socket_object(io_service_object) 
  • Invocar el método de aceptación del objeto aceptador para establecer la conexión. 
     
acceptor_server.accept(server_socket);
  • El método read_until() obtiene un mensaje del búfer que almacena datos durante la comunicación. Aquí estamos usando «\n» como delimitador de salida, lo que significa que seguiremos leyendo datos del búfer hasta que encontremos «\n» y los almacenemos. 
     
// Create buffer for storing
boost::asio::streambuf buf;

boost::asio::read_until(socket, buf, "\n");
string data = boost::asio::buffer_cast(buf.data());
  • El método write() escribe datos en el búfer tomando el objeto de socket y el mensaje como parámetro. 
     
boost::asio::write(
  socket, 
  boost::asio::buffer(message + "\n"));

Aplicación del lado del cliente: a continuación se muestran los diversos pasos para crear la aplicación del lado del cliente: 
 

  • Importando boost/asio.hpp. 
     
#include <boost/asio.hpp>
  • Creando objeto de io_service para cliente. 
     
boost::asio::io_service io_service_object;
  • Creando el objeto tcp::socket para el cliente. 
     
boost::asio::ip::tcp::socket
  socket_object(io_service_object) 
  • Invocando el método de conexión del objeto de socket para iniciar la conexión con el servidor usando localhost (IP 127.0.0.1) y conectándose al mismo puerto 9999. 
     
client_socket.connect(
  tcp::endpoint(
    address::from_string("127.0.0.1"), 
    9999 ));
  • read_until() y write() seguirán siendo los mismos para nuestra aplicación cliente, como el lado del servidor.

A continuación se muestra la implementación del enfoque anterior: Programa: 

servidor.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, "\n");
    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 + "\n"));
}

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 "\n" 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 "\n"
        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;
}


cliente.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, "\n");
    string data = buffer_cast<const char*>(buf.data());
    return data;
}

void sendData(tcp::socket& socket, const string& message)
{
    write(socket,
          buffer(message + "\n"));
}

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 "\n"
        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;
}

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *