tutorial.qbk

来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 2,067 行 · 第 1/5 页

QBK
2,067
字号
  ``''''''``  {  ``''''''``    start_accept();  ``''''''``  }  ``''''''``private:The function `start_accept()` creates a socket and initiates an asynchronous accept operation to wait for a new connection.  ``''''''``  void start_accept()  ``''''''``  {  ``''''''``    tcp_connection::pointer new_connection =  ``''''''``      tcp_connection::create(acceptor_.io_service());  ``''''''``    acceptor_.async_accept(new_connection->socket(),  ``''''''``        boost::bind(&tcp_server::handle_accept, this, new_connection,  ``''''''``          boost::asio::placeholders::error));  ``''''''``  }The function `handle_accept()` is called when the asynchronous accept operation initiated by `start_accept()` finishes. It services the client request, and then calls `start_accept()` to initiate the next accept operation.  ``''''''``  void handle_accept(tcp_connection::pointer new_connection,  ``''''''``      const boost::system::error_code& error)  ``''''''``  {  ``''''''``    if (!error)  ``''''''``    {  ``''''''``      new_connection->start();  ``''''''``      start_accept();  ``''''''``    }  ``''''''``  }[heading The tcp_connection class]We will use `shared_ptr` and `enable_shared_from_this` because we want to keep the `tcp_connection` object alive as long as there is an operation that refers to it.  ``''''''``class tcp_connection  ``''''''``  : public boost::enable_shared_from_this<tcp_connection>  ``''''''``{  ``''''''``public:  ``''''''``  typedef boost::shared_ptr<tcp_connection> pointer;  ``''''''``  static pointer create(boost::asio::io_service& io_service)  ``''''''``  {  ``''''''``    return pointer(new tcp_connection(io_service));  ``''''''``  }  ``''''''``  tcp::socket& socket()  ``''''''``  {  ``''''''``    return socket_;  ``''''''``  }In the function `start()`, we call boost::asio::async\_write() to serve the data to the client. Note that we are using boost::asio::async\_write(), rather than [link boost_asio.reference.basic_stream_socket.async_write_some ip::tcp::socket::async_write_some()], to ensure that the entire block of data is sent.  ``''''''``  void start()  ``''''''``  {The data to be sent is stored in the class member `message_` as we need to keep the data valid until the asynchronous operation is complete.  ``''''''``    message_ = make_daytime_string();When initiating the asynchronous operation, and if using boost::bind(), you must specify only the arguments that match the handler's parameter list. In this program, both of the argument placeholders (boost::asio::placeholders::error and boost::asio::placeholders::bytes\_transferred) could potentially have been removed, since they are not being used in `handle_write()`.  ``''''''``    boost::asio::async_write(socket_, boost::asio::buffer(message_),  ``''''''``        boost::bind(&tcp_connection::handle_write, shared_from_this(),  ``''''''``          boost::asio::placeholders::error,  ``''''''``          boost::asio::placeholders::bytes_transferred));Any further actions for this client connection are now the responsibility of `handle_write()`.  ``''''''``  }  ``''''''``private:  ``''''''``  tcp_connection(boost::asio::io_service& io_service)  ``''''''``    : socket_(io_service)  ``''''''``  {  ``''''''``  }  ``''''''``  void handle_write(const boost::system::error_code& /*error*/,  ``''''''``      size_t /*bytes_transferred*/)  ``''''''``  {  ``''''''``  }  ``''''''``  tcp::socket socket_;  ``''''''``  std::string message_;  ``''''''``};[heading Removing unused handler parameters]You may have noticed that the `error`, and `bytes_transferred` parameters are not used in the body of the `handle_write()` function. If parameters are not needed, it is possible to remove them from the function so that it looks like:  ``''''''``  void handle_write()  ``''''''``  {  ``''''''``  }The boost::asio::async\_write() call used to initiate the call can then be changed to just:  ``''''''``  boost::asio::async_write(socket_, boost::asio::buffer(message_),  ``''''''``      boost::bind(&tcp_connection::handle_write, shared_from_this()));See the [link boost_asio.tutorial.tutdaytime3.src full source listing]Return to the [link boost_asio.tutorial tutorial index]Previous: [link boost_asio.tutorial.tutdaytime2 Daytime.2 - A synchronous TCP daytime server]Next: [link boost_asio.tutorial.tutdaytime4 Daytime.4 - A synchronous UDP daytime client][section:src Source listing for Daytime.3]  ``''''''``//  ``''''''``// server.cpp  ``''''''``// ~~~~~~~~~~  ``''''''``//  ``''''''``// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)  ``''''''``//  ``''''''``// Distributed under the Boost Software License, Version 1.0. (See accompanying  ``''''''``// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)  ``''''''``//  ``''''''``#include <ctime>  ``''''''``#include <iostream>  ``''''''``#include <string>  ``''''''``#include <boost/bind.hpp>  ``''''''``#include <boost/shared_ptr.hpp>  ``''''''``#include <boost/enable_shared_from_this.hpp>  ``''''''``#include <boost/asio.hpp>  ``''''''``using boost::asio::ip::tcp;  ``''''''``std::string make_daytime_string()  ``''''''``{  ``''''''``  using namespace std; // For time_t, time and ctime;  ``''''''``  time_t now = time(0);  ``''''''``  return ctime(&now);  ``''''''``}  ``''''''``class tcp_connection  ``''''''``  : public boost::enable_shared_from_this<tcp_connection>  ``''''''``{  ``''''''``public:  ``''''''``  typedef boost::shared_ptr<tcp_connection> pointer;  ``''''''``  static pointer create(boost::asio::io_service& io_service)  ``''''''``  {  ``''''''``    return pointer(new tcp_connection(io_service));  ``''''''``  }  ``''''''``  tcp::socket& socket()  ``''''''``  {  ``''''''``    return socket_;  ``''''''``  }  ``''''''``  void start()  ``''''''``  {  ``''''''``    message_ = make_daytime_string();  ``''''''``    boost::asio::async_write(socket_, boost::asio::buffer(message_),  ``''''''``        boost::bind(&tcp_connection::handle_write, shared_from_this(),  ``''''''``          boost::asio::placeholders::error,  ``''''''``          boost::asio::placeholders::bytes_transferred));  ``''''''``  }  ``''''''``private:  ``''''''``  tcp_connection(boost::asio::io_service& io_service)  ``''''''``    : socket_(io_service)  ``''''''``  {  ``''''''``  }  ``''''''``  void handle_write(const boost::system::error_code& /*error*/,  ``''''''``      size_t /*bytes_transferred*/)  ``''''''``  {  ``''''''``  }  ``''''''``  tcp::socket socket_;  ``''''''``  std::string message_;  ``''''''``};  ``''''''``class tcp_server  ``''''''``{  ``''''''``public:  ``''''''``  tcp_server(boost::asio::io_service& io_service)  ``''''''``    : acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))  ``''''''``  {  ``''''''``    start_accept();  ``''''''``  }  ``''''''``private:  ``''''''``  void start_accept()  ``''''''``  {  ``''''''``    tcp_connection::pointer new_connection =  ``''''''``      tcp_connection::create(acceptor_.io_service());  ``''''''``    acceptor_.async_accept(new_connection->socket(),  ``''''''``        boost::bind(&tcp_server::handle_accept, this, new_connection,  ``''''''``          boost::asio::placeholders::error));  ``''''''``  }  ``''''''``  void handle_accept(tcp_connection::pointer new_connection,  ``''''''``      const boost::system::error_code& error)  ``''''''``  {  ``''''''``    if (!error)  ``''''''``    {  ``''''''``      new_connection->start();  ``''''''``      start_accept();  ``''''''``    }  ``''''''``  }  ``''''''``  tcp::acceptor acceptor_;  ``''''''``};  ``''''''``int main()  ``''''''``{  ``''''''``  try  ``''''''``  {  ``''''''``    boost::asio::io_service io_service;  ``''''''``    tcp_server server(io_service);  ``''''''``    io_service.run();  ``''''''``  }  ``''''''``  catch (std::exception& e)  ``''''''``  {  ``''''''``    std::cerr << e.what() << std::endl;  ``''''''``  }  ``''''''``  return 0;  ``''''''``}Return to [link boost_asio.tutorial.tutdaytime3 Daytime.3 - An asynchronous TCP daytime server][endsect][endsect][section:tutdaytime4 Daytime.4 - A synchronous UDP daytime client]This tutorial program shows how to use asio to implement a client application with UDP.  ``''''''``#include <iostream>  ``''''''``#include <boost/array.hpp>  ``''''''``#include <boost/asio.hpp>  ``''''''``using boost::asio::ip::udp;The start of the application is essentially the same as for the TCP daytime client.  ``''''''``int main(int argc, char* argv[])  ``''''''``{  ``''''''``  try  ``''''''``  {  ``''''''``    if (argc != 2)  ``''''''``    {  ``''''''``      std::cerr << "Usage: client <host>" << std::endl;  ``''''''``      return 1;  ``''''''``    }  ``''''''``    boost::asio::io_service io_service;We use an [link boost_asio.reference.ip__udp.resolver ip::udp::resolver] object to find the correct remote endpoint to use based on the host and service names. The query is restricted to return only IPv4 endpoints by the [link boost_asio.reference.ip__udp.v4 ip::udp::v4()] argument.  ``''''''``    udp::resolver resolver(io_service);  ``''''''``    udp::resolver::query query(udp::v4(), argv[1], "daytime");The [link boost_asio.reference.ip__basic_resolver.resolve ip::udp::resolver::resolve()] function is guaranteed to return at least one endpoint in the list if it does not fail. This means it is safe to dereference the return value directly.  ``''''''``    udp::endpoint receiver_endpoint = *resolver.resolve(query);Since UDP is datagram-oriented, we will not be using a stream socket. Create an [link boost_asio.reference.ip__udp.socket ip::udp::socket] and initiate contact with the remote endpoint.  ``''''''``    udp::socket socket(io_service);  ``''''''``    socket.open(udp::v4());  ``''''''``    boost::array<char, 1> send_buf  = { 0 };  ``''''''``    socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);Now we need to be ready to accept whatever the server sends back to us. The endpoint on our side that receives the server's response will be initialised by [link boost_asio.reference.basic_datagram_socket.receive_from ip::udp::socket::receive_from()].  ``''''''``    boost::array<char, 128> recv_buf;  ``''''''``    udp::endpoint sender_endpoint;  ``''''''``    size_t len = socket.receive_from(  ``''''''``        boost::asio::buffer(recv_buf), sender_endpoint);  ``''''''``    std::cout.write(recv_buf.data(), len);  ``''''''``  }Finally, handle any exceptions that may have been thrown.  ``''''''``  catch (std::exception& e)  ``''''''``  {  ``''''''``    std::cerr << e.what() << std::endl;  ``''''''``  }  ``''''''``  return 0;  ``''''''``}See the [link boost_asio.tutorial.tutdaytime4.src full source listing]Return to the [link boost_asio.tutorial tutorial index]Previous: [link boost_asio.tutorial.tutdaytime3 Daytime.3 - An asynchronous TCP daytime server]Next: [link boost_asio.tutorial.tutdaytime5 Daytime.5 - A synchronous UDP daytime server][section:src Source listing for Daytime.4]  ``''''''``//  ``''''''``// client.cpp  ``''''''``// ~~~~~~~~~~  ``''''''``//  ``''''''``// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)  ``''''''``//  ``''''''``// Distributed under the Boost Software License, Version 1.0. (See accompanying  ``''''''``// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)  ``''''''``//  ``''''''``#include <iostream>  ``''''''``#include <boost/array.hpp>  ``''''''``#include <boost/asio.hpp>  ``''''''``using boost::asio::ip::udp;  ``''''''``int main(int argc, char* argv[])  ``''''''``{  ``''''''``  try  ``''''''``  {  ``''''''``    if (argc != 2)  ``''''''``    {  ``''''''``      std::cerr << "Usage: client <host>" << std::endl;  ``''''''``      return 1;  ``''''''``    }  ``''''''``    boost::asio::io_service io_service;  ``''''''``    udp::resolver resolver(io_service);  ``''''''``    udp::resolver::query query(udp::v4(), argv[1], "daytime");  ``''''''``    udp::endpoint receiver_endpoint = *resolver.resolve(query);  ``''''''``    udp::socket socket(io_service);  ``''''''``    socket.open(udp::v4());  ``''''''``    boost::array<char, 1> send_buf  = { 0 };  ``''''''``    socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);  ``''''''``    boost::array<char, 128> recv_buf;  ``''''''``    udp::endpoint sender_endpoint;  ``''''''``    size_t len = socket.receive_from(  ``''''''``        boost::asio::buffer(recv_buf), sender_endpoint);  ``''''''``    std::cout.write(recv_buf.data(), len);  ``''''''``  }  ``''''''``  catch (std::exception& e)  ``''''''``  {  ``''''''``    std::cerr << e.what() << std::endl;  ``''''''``  }  ``''''''``  return 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?