Boost ASIO Learning (vii) Network Foundation connectors and receivers (TCP example)

Source: Internet
Author: User

http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-
Started-with-boostasio?pg=8

7. Networking basics:connectors and acceptors (TCP)
Let's learn the TCP network programming for boost. The previous chapter has introduced the network system framework. We just need to learn the network API functions to

We first learn how to synchronize the connected hosts. Our code runs as a client, using the Tcp::socket object. The Tcp::socket object has different socket types for different protocols. We need to confirm the use of the correct object. When we connect a remote host
, we need to get the remote address. In order to achieve this goal, we use Tcp::resolver.

#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include < boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <boost/lexical_cast.hpp> #include < iostream> #include <string>boost::mutex global_stream_lock;void workerthread (boost::shared_ptr< boost:: Asio::io_service > Io_service) {global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_ ID () << "Thread Start" << std::endl;global_stream_lock.unlock (); while (true) {Try{boost::system::error_ Code ec;io_service->run (EC), if (EC) {Global_stream_lock.lock (); Std::cout << "[" << Boost::this_thread: : get_id () << "] Error:" << EC << Std::endl;global_stream_lock.unlock ();} break;} catch (Std::exception & ex) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id ( ) << "] Exception:" << ex.what () << std::endl;global_stream_lock.unlock ();}} GLobal_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] Thread Finish" < < Std::endl;global_stream_lock.unlock ();} int main (int argc, char * argv[]) {boost::shared_ptr< boost::asio::io_service > Io_service (New Boost::asio::io_ser Vice);boost::shared_ptr< boost::asio::io_service::work > work (New Boost::asio::io_service::work (*io_service) );boost::shared_ptr< boost::asio::io_service::strand > Strand (New Boost::asio::io_service::strand (*io_ Service), Global_stream_lock.lock (), Std::cout << "[" << boost::this_thread::get_id () << "] press [ Return] to exit. "<< Std::endl;global_stream_lock.unlock (); boost::thread_group worker_threads;for (int x = 0; x &lt ; 2; ++x) {Worker_threads.create_thread (Boost::bind (&workerthread, Io_service));} Boost::asio::ip::tcp::socket sock (*io_service); try{boost::asio::ip::tcp::resolver Resolver (*io_service); Boost:: Asio::ip::tcp::resolver::query Query ("www.google.com", boost::lexical_cast< std::string >); Boost::asio::ip::tcp::resolver::iterator iterator = Resolver.resolve (query); Boost::asio::ip::tcp::endpoint endpoint = *iterator;global_stream_lock.lock (); std::cout << "Connecting to:" << endpoint << std::endl;global_stream_lock.unlock (); Sock.connect (endpoint);} catch (Std::exception & ex) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id ( ) << "] Exception:" << ex.what () << std::endl;global_stream_lock.unlock ();} Std::cin.get (); Boost::system::error_code Ec;sock.shutdown (Boost::asio::ip::tcp::socket::shutdown_both, EC); Sock.close (EC); Io_service->stop (); Worker_threads.join_all (); return 0;}

  

This example simply opens up a connection. The program returns the port and IP it is actually trying to connect to. If we open a command prompt window to run "netstat-n", we will see the TCP connection of this program
In the example we use the query object to reuse this code. The code is more suitable for numbers than strings, so we use functions to convert ports from numbers to strings.

Sometimes we may need to connect to a remote host asynchronously. For example, the GUI program opens the connection via a button, but we do not want the GUI interface to freeze until the connection is complete. The Boost::asio provides an asynchronous way to connect.
Use Bind shared_ptr.

#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include < boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <boost/lexical_cast.hpp> #include < iostream> #include <string>boost::mutex global_stream_lock;void workerthread (boost::shared_ptr< boost:: Asio::io_service > Io_service) {global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_ ID () << "Thread Start" << std::endl;global_stream_lock.unlock (); while (true) {Try{boost::system::error_ Code ec;io_service->run (EC), if (EC) {Global_stream_lock.lock (); Std::cout << "[" << Boost::this_thread: : get_id () << "] Error:" << EC << Std::endl;global_stream_lock.unlock ();} break;} catch (Std::exception & ex) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id ( ) << "] Exception:" << ex.what () << std::endl;global_stream_lock.unlock ();}} GLobal_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] Thread Finish" < < Std::endl;global_stream_lock.unlock ();} void OnConnect (const Boost::system::error_code & EC, boost::shared_ptr< boost::asio::ip::tcp::socket > sock) {if (EC) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] Error:" << EC << Std::endl;global_stream_lock.unlock ();} Else{global_stream_lock.lock () std::cout << "[" << boost::this_thread::get_id () << "] connected!" << Std::endl;global_stream_lock.unlock ();}} int main (int argc, char * argv[]) {boost::shared_ptr< boost::asio::io_service > Io_service (New Boost::asio::io_ser Vice);boost::shared_ptr< boost::asio::io_service::work > work (New Boost::asio::io_service::work (*io_service) );boost::shared_ptr< boost::asio::io_service::strand > Strand (New Boost::asio::io_service::strand (*io_ Service)); Global_stream_lock.locK (); Std::cout << "[" << boost::this_thread::get_id () << "] press [Return] to exit." << Std::endl;g Lobal_stream_lock.unlock (); boost::thread_group worker_threads;for (int x = 0; x < 2; ++x) {Worker_threads.create_ Thread (Boost::bind (&workerthread, Io_service));} boost::shared_ptr< boost::asio::ip::tcp::socket > sock (New Boost::asio::ip::tcp::socket (*io_service)); try{ Boost::asio::ip::tcp::resolver Resolver (*io_service); Boost::asio::ip::tcp::resolver::query query ("www.google.com ", boost::lexical_cast< std::string >); Boost::asio::ip::tcp::resolver::iterator iterator = Resolver.resolve (query); Boost::asio::ip::tcp::endpoint endpoint = *iterator;global_stream_lock.lock (); std::cout << "Connecting to:" << endpoint << std::endl;global_stream_lock.unlock (); Sock->async_connect ( Endpoint, Boost::bind (OnConnect, _1, sock));} catch (Std::exception & ex) {Global_stream_lock.lock (); Std::cout << "[" << boost:: this_thread::get_id () << "] Exception:" << ex.what () << std::endl;global_stream_lock.unlock ();} Std::cin.get (); Boost::system::error_code Ec;sock->shutdown (Boost::asio::ip::tcp::socket::shutdown_both, EC); Sock->close (EC); Io_service->stop (); Worker_threads.join_all (); return 0;}

  

If you want to pass a Boost::asio object, we generally use the SHARED_PTR smart pointer. Because most objects are non-copyable that cannot be copied, and we determine that the object remains valid for the duration of the call.
We use bind to set up our custom handlers.
The last example we connect to the remote address asynchronously

#include <boost/asio.hpp> #include <boost/shared_ptr.hpp> #include <boost/thread.hpp> #include < boost/thread/mutex.hpp> #include <boost/bind.hpp> #include <boost/lexical_cast.hpp> #include < iostream> #include <string>boost::mutex global_stream_lock;void workerthread (boost::shared_ptr< boost:: Asio::io_service > Io_service) {global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_ ID () << "Thread Start" << std::endl;global_stream_lock.unlock (); while (true) {Try{boost::system::error_ Code ec;io_service->run (EC), if (EC) {Global_stream_lock.lock (); Std::cout << "[" << Boost::this_thread: : get_id () << "] Error:" << EC << Std::endl;global_stream_lock.unlock ();} break;} catch (Std::exception & ex) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id ( ) << "] Exception:" << ex.what () << std::endl;global_stream_lock.unlock ();}} GLobal_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] Thread Finish" < < Std::endl;global_stream_lock.unlock ();} void OnAccept (const Boost::system::error_code & EC, boost::shared_ptr< boost::asio::ip::tcp::socket > sock) { if (EC) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] Error:" < < EC << Std::endl;global_stream_lock.unlock ();} Else{global_stream_lock.lock () std::cout << "[" << boost::this_thread::get_id () << "] accepted!" << Std::endl;global_stream_lock.unlock ();}} int main (int argc, char * argv[]) {boost::shared_ptr< boost::asio::io_service > Io_service (New Boost::asio::io_ser Vice);boost::shared_ptr< boost::asio::io_service::work > work (New Boost::asio::io_service::work (*io_service) );boost::shared_ptr< boost::asio::io_service::strand > Strand (New Boost::asio::io_service::strand (*io_ Service)); Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id () << "] press [Return] to exit." << Std::endl;glo Bal_stream_lock.unlock (); boost::thread_group worker_threads;for (int x = 0; x < 2; ++x) {Worker_threads.create_thread (Boost::bind (&workerthread, Io_service));} boost::shared_ptr< boost::asio::ip::tcp::acceptor > Acceptor (New Boost::asio::ip::tcp::acceptor (*io_service) );boost::shared_ptr< boost::asio::ip::tcp::socket > sock (New Boost::asio::ip::tcp::socket (*io_service)); try{ Boost::asio::ip::tcp::resolver Resolver (*io_service); Boost::asio::ip::tcp::resolver::query query ("127.0.0.1", boost::lexical_cast< std::string > (7777)); Boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve (query); Acceptor->open (Endpoint.protocol ()); Acceptor->set_option (Boost::asio::ip::tcp::acceptor::reuse_address ( FALSE); Acceptor->bind (endpoint); Acceptor->listen (boost::asio::socket_base::max_connections); acceptor- >async_accept (*sock, Boost::bind (OnAccept, _1, sock)); Global_stream_lock.lock (); Std::cout << "Listening on:" << Endpoint << Std::endl;global_stream_lock.unlock ();} catch (Std::exception & ex) {Global_stream_lock.lock (); Std::cout << "[" << boost::this_thread::get_id ( ) << "] Exception:" << ex.what () << std::endl;global_stream_lock.unlock ();} Std::cin.get (); Boost::system::error_code ec;acceptor->close (EC); Sock->shutdown (boost::asio::ip::tcp:: Socket::shutdown_both, EC); Sock->close (EC); Io_service->stop (); Worker_threads.join_all (); return 0;}

  

This example is very similar to the previous example. In fact, just a little bit of change. As mentioned before, the ASIO library is a very good library. We learn some of his components to understand other components of it.
Running the above code on port 7777, we can run the command "telnet localhost 7777" from the command-line window and open a connection to the server to fire the OnAccept function in the code.

However, the server will no longer be able to receive more connections, because we only call async_accept once and only one socket object. We will deal with the design strategy of the server later. We just need to open the core API.
example, we use the error variable to confirm that no exception occurred.
Discuss the basic connection and reception. The next section will discuss the socket read and write

Boost ASIO Learning (vii) Network Foundation connectors and receivers (TCP example)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.