Operações síncronas E/S
Depois que a conexão é estabelecida, o cliente e o servidor podem se comunicar. Como na API sockets do UNIX
, o boost::asio
também fornece as funções send
e receive
Use basic_stream_socket
como exemplo e um par de implementações assim:
template <typename ConstBufferSequence>
std::size_t send(const ConstBufferSequence& buffers)
{
......
}
......
template <typename MutableBufferSequence>
std::size_t receive(const MutableBufferSequence& buffers)
{
......
}
Observe que os tipos de buffer de send/receive
são ConstBufferSequence/MutableBufferSequence
, e podemos usar a função boost::asio::buffer
para construir tipos relacionados.
Abaixo está um programa cliente que envia "Hello world!
" Para o servidor após o estabelecimento da conexão:
#include <boost/asio.hpp>
#include <iostream>
int main()
{
try
{
boost::asio::io_context io_context;
boost::asio::ip::tcp::endpoint endpoint{
boost::asio::ip::make_address("10.217.242.61"),
3303};
boost::asio::ip::tcp::tcp::socket socket{io_context};
socket.connect(endpoint);
std::cout << "Connect to " << endpoint << " successfully!\n";
socket.send(boost::asio::buffer("Hello world!"));
}
catch (std::exception& e)
{
std::cerr << e.what() << '\n';
return -1;
}
return 0;
}
O programa servidor que aguarda o recebimento da saudação do cliente:
#include <boost/asio.hpp>
#include <iostream>
int main()
{
try
{
boost::asio::io_context io_context;
boost::asio::ip::tcp::acceptor acceptor{
io_context,
boost::asio::ip::tcp::endpoint{boost::asio::ip::tcp::v4(), 3303}};
while (1)
{
boost::asio::ip::tcp::socket socket{io_context};
acceptor.accept(socket);
std::cout << socket.remote_endpoint() << " connects to " << socket.local_endpoint() << '\n';
char recv_str[1024] = {};
socket.receive(boost::asio::buffer(recv_str));
std::cout << "Receive string: " << recv_str << '\n';
}
}
catch (std::exception& e)
{
std::cerr << e.what() << '\n';
return -1;
}
return 0;
}
Compile e execute os programas. O cliente exibirá o seguinte:
$ ./client
Connect to 10.217.242.61:3303 successfully!
Servidor exibirá seguinte:
$ ./server
10.217.242.21:64776 connects to 10.217.242.61:3303
Receive string: Hello world!
Se nenhum erro ocorrer, o send
pode garantir que pelo menos um byte seja enviado com sucesso, e você deve verificar o valor de retorno para ver se todos os bytes foram enviados com sucesso ou não. receive
é semelhante a send
. O boost::asio::basic_stream_socket
também fornece read_some
e write_some
, que têm as mesmas funções que receive
e send
.
Se não nos preocuparmos em verificar o estado do meio (bytes parciais são enviados com sucesso), e apenas nos importarmos se todos os bytes serão enviados com sucesso ou não, podemos usar o boost::asio::write
que usa o write_some
por baixo. Da mesma forma, não é difícil adivinhar o que boost::asio::read
faz.