Usando Sockets com C++ – Parte 2: Cliente

por Fabio A. Mazzarino

Dando sequência à série de desenvolvimento com sockets usando boost::Asio em C++ o post vai demonstrar como fazer um cliente echo que procura o servidor na rede local, nos moldes do que já foi feito com C.

Primeiro o código:

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

int main() {
    boost::asio::io_service ioservice;
    boost::asio::ip::tcp::socket socket(ioservice);

    std::string msg = "abc\n";
    std::cout << "Looking for echo server on 192.168.0.*" << std::endl;
    for (int ct = 1; ct <= 255; ct++) {
        std::stringstream ip;
        ip << "192.168.0." << ct;

        try {
            socket.connect(
                boost::asio::ip::tcp::endpoint(
                    boost::asio::ip::address::from_string(ip.str()), 
                    5001 
                )
            );
        } catch (...) {
            continue;
        }

        boost::system::error_code error;
        boost::asio::write(socket, boost::asio::buffer(msg), error);
        if (error) {
            std::cout << "Cannot send data to echo server on " << ip.str() << ":5001" << std::endl;
            continue;
        }

        boost::asio::streambuf recvbuffer;
        boost::asio::read(socket, recvbuffer, boost::asio::transfer_all(), error);
        if (error && error != boost::asio::error::eof) {
            std::cout << "Cannot receive data from echo server on " << ip.str() << ":5001" << std::endl;
            continue;
        }

        std::string rcvddata = boost::asio::buffer_cast<const char*>(recvbuffer.data());
        if (rcvddata == "abc\n") {
            std::cout << "Found echo server on " << ip.str() << ":5001" << std::endl;
            break;
        }
    }
}

Lembrando que para compilar o código é preciso adicionar duas bibliotecas na compilação:

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

Primeiro precisamos criar um io_service e usá-lo para criar um socket. Já dentro do loop vamos montar o endereço de IP e usar o método connect do objeto socket pra efetuar a conexão, os argumentos precisam ser o endereço, através do objeto address, e a porta.

Aí basta usar os métodos estáticos write e read para fazer a comunicação. No exemplo não é necessário fazer a desconexão porque o socket perde escopo no final do loop e fecha a conexão automaticamente.

Esta é a forma mais simples de utilizar sockets com boost::Asio, nos próximos posts vamos ver como utilzar a forma assíncrona.