Usando Sockets com C++ – Parte 1: Servidor

por Fabio A. Mazzarino

Nos dois posts anteriores foi demonstrado como utilizar sockets com C. Agora vamos ver a diferença entre C e C++, utilizando boost::Asio.

Boost é um conjunto de bibliotecas para C++ tão popular que é praticamente considerado padrão. Conta com uma grande opção de bibliotecas para os mais diversos fins, incluem bibliotecas para IO, funções matemáticas, threads, processamento paralelo, date/time, dentre diversas outras.

No exemplo deste post vamos usar a versão síncrona do boost::Asio. Existem ainda a versão assíncrona, e a versão orientada a objeto.

Vamos ao código:


#include <iostream>
#include <string>
#include <boost/asio.hpp>

int main() {
    boost::asio::io_service ioservice;
    boost::asio::ip::tcp::acceptor serveracceptor(ioservice, 
        boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 5001)
    );

    std::cout << "Echo server ready on port 5001" << std::endl;
    for (; ; ) {
        boost::asio::ip::tcp::socket serversocket(ioservice);
        serveracceptor.accept(serversocket);
        std::cout << "Connection received" << std::endl;
        int childpid = fork();
        if (childpid != 0)
            continue;
        boost::asio::streambuf buffer;
        boost::asio::read_until(serversocket, buffer, "\n");
        boost::asio::write(serversocket, buffer);
    }
 }

Para compilar o código precisamos utilizar duas bibliotecas: pthread e boost_system, portanto a linha de comando fica assim:

g++ -lpthread -lboost_system -o echoserver echoserver.cpp

Primeiro precisamos crar um io_service, e utlizá-lo para configurar um novo acceptor, quando definimos o protocolo e a porta. No loop principal da aplicação vamos criar um socket e associá-lo a função blocante accept do objeto acceptor que criamos fora do loop.

Assim que receber uma conexão um fork garante a disponibilidade de conexão para o próximo cliente, tal qual no nosso último exemplo em C ANSI, e então utilizamos as funções read_until e write para receber e enviar dados.

Para o teste do servidor vamos utilizar telnet:

$ telnet 192.168.0.19 5001
Trying 192.168.0.19...
Connected to 192.168.0.19.
Escape character is '^]'.
help
help
Connection closed by foreign host.

No próximo post vamos fazer o cliente, tal qual foi desenvolvido em C.