"Boost.asio C + + Network Programming"
Libtorrent used the Boost.asio
Support
Network
COM serial ports
Files
Implementing synchronous/asynchronous input and output
Read (stream, buffer)
Async_read (stream, buffer)
Write (stream, buffer)
Async_write (stream, buffer)
TCP UDP IMCP
You can extend it to support your own protocols according to your needs.
If you use synchronous mode because it is blocking mode, server clients tend to use multithreading
Decide to use synchronous or asynchronous mode as early as possible before programming
Asynchronous mode debugging more difficult synchronous multithreaded asynchronous single thread
Example: Synchronizing a client
Using Boost::asio;
Io_service Service;
Ip::tcp::endpoint EP (Ip::address::from_string ("127.0.0.1", 2001);
Ip::tcp::socket (service);
Sock.connect (EP);
Boost.asio uses Io_service to the operating system ' s input/output services.
Synchronizing servers
Using Boost::asio;
typedef boost::shared_ptr<ip::tcp::socket> SOCKET_PTR;
Io_service Service;
Ip::tcp::endpoint EP (IP::TCP::V4 (), 2001)); Listen on 2001
ip::tcp::acceptor ACC (service, EP);
while (true)
{
socket_ptr sock (new Ip::tcp::socket (service));
Acc.accept (*sockt);
Boost::thread (Boost::bind (client_session, sock);
}
void Client_session (Socket_ptr sock)
{
while (true)
{
char data[512];
size_t len = sock->read_some (buffer (data));
if (len > 0)
write (*sock, buffer ("OK", 2));
}
}
Asynchronous client
Using Boost::asio;
Io_service Service;
Ip::tcp::endpoint EP (Ip::address::from_string ("127.0.0.1", 2001);
Ip::tcp::socket sock (service);
Sock.async_connect (EP, Connect_handler);
Service.run ();
void Connect_handler (const boost::system::error_code& EC)
{
//Here we known we connected successfully
If EC indicates success
}
//Service.run () exit until all asynchronous operations are complete
Asynchronous server
Using Boost::asio;
typedef boost::shared_ptr<ip::tcp::socket> SOCKET_PTR;
Io_service Service;
Ip::tcp::endpoint EP (IP::TCP::V4 (), 2001);
Ip::tcp::acceptor ACC (service, EP);
Socket_ptr Sock (new Ip::tcp::socket (service));
Start_accept (sock);
Service.run ();
void Start_accept (Socket_ptr sock)
{
acc.async_accept (*sock, Boost::bind (handle_accept, sock, _1));
}
void Handle_accept (Socket_ptr sock, const boost::system::error_code& err)
{
if (err)
return;
At this point, you can read/write to the socket
socket_ptr sock (new Ip::tcp::socket (service));
Start_accept (sock);
}
Exception handling
Using Boost::asio;
Ip::tcp::endpoint EP;
Ip::tcp::socket sock (service);
Throws an exception Boost::system::system_error
try
{
sock.connect (EP);
} catch (Boost::system::system_error & E)
{std::cout << e.code () << Std::endl;}
Boost::system::error_code err;
Return error code
sock.connect (EP, err);
if (err)
std::cout << err << Std::endl;
The async pattern always returns an error code, and the async function does not throw an exception.
Char data[512];
Boost::system::error_code error;
size_t length = sock.read_some (buffer (data), error);
if (Error = = error::eof)
return;//Connection closed
boost/asio/error.hpp
Io_service is thread-safe.
Multiple threads can call Io_service::run ()
The callback function executes in any thread that calls run ().
The socket class is not thread safe
One thread should be avoided to read another thread to write the same socket
It is meaningless to use utility in multiple threads, so it is not thread-safe.
Most of them is meant to just is used for a short time, then
Go out of scope.
In addition to the network:
Signal
void Signal_handler (const Boost::system::error_code & err, int signal)
{
//log this, and terminate Applicati On
}
boost::asio::signal_set sig (Service, SIGINT, SIGTERM);
Sig.async_wait (Signal_handler);
Serial
Using Boost.asio, you can easily connect to a serial port. The port name is COM7 on
Windows, OR/DEV/TTYS0 on POSIX platforms:
io_service service;
Serial_port SP (Service, "COM7");
Serial_port::baud_rate rate (9600);
Sp.set_option (rate);
See Boost.asio C + + Network programming.pdf 14 page for more details
Timer
Sock.async_read_some (buffer (data,));
Deadline_timer T (service, boost::p osix_time::milliseconds);
T.async_wait (&deadline_handler);
Service.run ();
Sync Timer and sleep equivalence
Boost::this_thread::sleep (+);
-or-
Deadline_timer t (service, boost::p osix_time::milliseconds);
T.wait ();
The following code does not make sense, and multiple service instances are running in the same thread
Because Service_[1].run () needs to wait for Service_[0].run () to complete.
for (int i = 0; i < 2; ++i)
Service_[i].run ();
1.
Thread 1 S.run () The Call of all callback functions is synchronous in that thread
2.
Thread 1 S.run () All callback functions are assigned to multiple threads to execute asynchronously
Thread 2 S.run ()
3.
Thread 1 S1.run ()
Thread 2 S2.run ()
A method that keeps the run () function running in a callback function performs a new asynchronous operation the other way is to simulate some work for it,
By using the following code snippet:
typedef BOOST::SHARED_PTR WORK_PTR;
Work_ptr dummy_work (New Io_service::work (Service_));
The preceding code would make sure this service_.run () never stops unless you
Either use Service_.stop () or dummy_work.reset (0); Destroy Dummy_work.
Service.post ()
Io_service::strand strand_one (service);
Service.post (Strand_one.wrap (Boost::bind (func, i));
Service.dispatch ()
If the current process calls run (), dispatch () waits until the direct task is executed.
Post () is returned immediately
Boost::function
Boost::thread_group Threads;
Threads.create_thread (func1);
Threads.create_thread (FUNC2);
Threads.join_all ();