A guide to getting started with boost::asio By Drew Benton 读后小结

A guide to getting started with boost::asio  by Drew Benton 

地址 https://www.gamedev.net/blogs/entry/2249317-a-guide-to-getting-started-with-boostasio/

读后小结:

io_service: 从boost v1.66起io_service变成了io_context,二者有一定差异,但基本应用相同。

io_service run() member function: the run() function blocks until all work has finished and there are no more handlers to be dispatched, or until the io_service has been stopped.

io_service poll() member function: runs the io_service object's event processing loop to execute ready handlers.

To get the io_service working for us, we have to use the run or poll family of functions. Run will block and wait for work if we assign it a work object while the poll function does not. 

io_service stop() member function will signal the io_service that all work should be stopped, so after the current batch of work finishes, no more work will be done. 

work class: is a "class to inform the io_service when it has work to do." In other words, as long as an io_service has a work object associated with it, it will never run out of stuff to do. 

Choose to use stop() or destroy the work object: if we had associated a work object with the io_service and wanted to let all queued work finish, we would not call stop but rather destroy the work object. Care has to be taken though. If we want all work to finish but keep giving the io_service more things to do, then it will never exit! In that case, at some point, we would want to call the stop function to ensure the system actually stops.

use io_service with boost::bind: if we were to try to use io_service with boost::bind, we would get a non-copyable error, since the io_service cannot be copied and that is what boost::bind does for us behind the scenes. To get around this, we must make use of shared_ptr. Rather than using a regular io_service object, we must use a shared_ptr object of io_service and pass that around. The shared_ptr is a reference counted smart pointer so it is copyable and thus compatible with boost::bind. The same applies for many other non-copyable objects as well; we have to wrap them in shared_ptrs to pass them if we need to.

io_service post() and dispatch(): The post function "is used to ask the io_service to execute the given handler, but without allowing the io_service to call the handler from inside this function."  The dispatch function "guarantees that the handler will only be called in a thread in which the run(), run_one(), poll() or poll_one() member functions is currently being invoked. The handler may be executed inside this function if the guarantee can be met."
So the fundamental difference is that dispatch will execute the work right away if it can and queue it otherwise while post queues the work no matter what. Both of the functionality are really important as the function we will use will depend on the context that it is being used in. 

The strand class "provides serialised handler execution." This means if we post work1 -> work2 -> work3 through a strand, no matter how many worker threads we have, it will be executed in that order. 

strand wrap() member function: Create a new handler that automatically dispatches the wrapped handler on the strand.

We have to use a boost::shared_ptr with most boost::asio objects if we wish to pass them around. This is because the objects themselves are non-copyable and we have to ensure the object remains valid while the handler is waiting to be called. 

boost::asio::ip::tcp::socket  used as a client to connect to a host. 

 boost::asio::ip::tcp::acceptor to setup such a "server" letting remote hosts connect to us? 

https://valelab4.ucsf.edu/svn/3rdpartypublic/boost/doc/html/boost_asio/reference/basic_stream_socket/async_read_some.html

basic_stream_socket::async_read_some

Start an asynchronous read.

template<
    typename MutableBufferSequence,
    typename ReadHandler>
void async_read_some(
    const MutableBufferSequence & buffers,
    ReadHandler handler);

This function is used to asynchronously read data from the stream socket. The function call always returns immediately.

Parameters

buffers

One or more buffers into which the data will be read. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.

handler

The handler to be called when the read operation completes. Copies will be made of the handler as required. The function signature of the handler must be:

void handler(
  const boost::system::error_code& error, // Result of operation.
  std::size_t bytes_transferred           // Number of bytes read.
); 

Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using boost::asio::io_service::post().

Remarks

The read operation may not read all of the requested number of bytes. Consider using the async_read function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.

Example

To read into a single data buffer use the buffer function as follows:

socket.async_read_some(boost::asio::buffer(data, size), handler);

See the buffer documentation for information on reading into multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.

async_write (1 of 4 overloads)

Start an asynchronous operation to write all of the supplied data to a stream.

template<
    typename AsyncWriteStream,
    typename ConstBufferSequence,
    typename WriteHandler>
void async_write(
    AsyncWriteStream & s,
    const ConstBufferSequence & buffers,
    WriteHandler handler);

This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:

  • All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
  • An error occurred.

This operation is implemented in terms of zero or more calls to the stream's async_write_some function, and is known as a composed operation. The program must ensure that the stream performs no other write operations (such as async_write, the stream's async_write_some function, or any other composed operations that perform writes) until this operation completes.

Parameters

s

The stream to which the data is to be written. The type must support the AsyncWriteStream concept.

buffers

One or more buffers containing the data to be written. Although the buffers object may be copied as necessary, ownership of the underlying memory blocks is retained by the caller, which must guarantee that they remain valid until the handler is called.

handler

The handler to be called when the write operation completes. Copies will be made of the handler as required. The function signature of the handler must be:

void handler(
  const boost::system::error_code& error, // Result of operation.

  std::size_t bytes_transferred           // Number of bytes written from the
                                          // buffers. If an error occurred,
                                          // this will be less than the sum
                                          // of the buffer sizes.
); 

Regardless of whether the asynchronous operation completes immediately or not, the handler will not be invoked from within this function. Invocation of the handler will be performed in a manner equivalent to using boost::asio::io_service::post().

Example

To write a single data buffer use the buffer function as follows:

boost::asio::async_write(s, boost::asio::buffer(data, size), handler);

See the buffer documentation for information on writing multiple buffers in one go, and how to use it with arrays, boost::array or std::vector.

 
发布了87 篇原创文章 · 获赞 64 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/wqfhenanxc/article/details/87008966