PS: At this point finally completed Boost.asio C + + network programming a book translation, this is my life the first full translation of the book, from the beginning of the stumbling, to the last little experience, I harvest a lot. I will organize and proofread this series of blogs, hoping that people who are interested can help me to provide a better and more professional reading experience for everyone.
Handle tracking information to a file
By default, the tracking information for a handle is output to the standard error stream (equivalent to Std::cerr). The likelihood that you want to redirect the output to another place is very high. For console applications, output and error output are exported to the same place, which is the console, by default. However, for a Windows (non-command line) app, the default error stream is null. you can redirect the error output from the command line, such as:some_application 2>err.txtor, if you are not very lazy, you can implement the code just like the following code snippet:
for Windows HANDLE h = CreateFile ("Err.txt", Generic_write, 0, 0, create_always, file_attribute_normal, 0 ); Setstdhandle (Std_error_handle, h); for unix int err_file = open ("Err.txt", o_wronly); Dup2 (Err_file, Stderr_fileno);
SSLBoost.asio provides some classes that support basic SSL. It uses OpenSSL in the background, so if you want to use SSL, first download OpenSSL from www.openssl.org and build it. You need to be aware that building OpenSSL is usually not a simple task, especially if you don't have a common compiler, such as visual Studio. If you build the Openssl,boost.asio successfully, there will be some encapsulation classes around it:
- Ssl::stream: It replaces ip:<protocol>::socket to tell you what to use
- Ssl::context: This is the context for the first handshake
- Ssl::rfc2818_verification: Using this class, you can easily authenticate a host name with a certificate according to the RFC 2818 protocol
First, you create and initialize the SSL context, and then use this context to open a socket connected to the specified remote host, and then do the SSL handshake. Once the handshake is over, you can useBoost.asio of read*/write* and other free functions. below is a link to Yahoo! Examples of HTTPS clients:
#include <boost/asio.hpp> #include <boost/asio/ssl.hpp> using namespace Boost::asio; Io_service Service;
int main (int argc, char* argv[]) {
typedef ssl::stream<ip::tcp::socket> Ssl_socket;
Ssl::context CTX (ssl::context::sslv23); ctx.set_default_verify_paths ();
Open an SSL socket to the specified host
Io_service Service;ssl_socket Sock (service, CTX);
Ip::tcp::resolver Resolver (service); std::string host = "www.yahoo.com"; ip::tcp::resolver::query query (host, "https") Connect (Sock.lowest_layer (), resolver.resolve (query));//SSL Handshake Sock.set_verify_mode (ssl::verify_none); sock.set_ Verify_callback (Ssl::rfc2818_verification (host)); Sock.handshake (ssl_socket::client);
std::string req = "get/index.html http/1.0\r\nhost:" + Host + "\r\naccept: */*\r\nconnection:close\r\n\r\n";
Write (sock, buffer (REQ.C_STR (), Req.length ())); Char buff[512]; Boost::system::error_code EC; while (!EC) {
int bytes = Read (sock, buffer (buff), EC);
Std::cout << std::string (buff, bytes); }
}
the first line can be very good self-release. When you connect to a remote host, you use Sock.lowest_layer (), that is, you use the underlying socket (because Ssl::stream is tightly encapsulated). The next three lines were shook. At the end of the handshake, you made an HTTP request using the Write () method of Booat.asio, and then read (read ()) all the incoming self. when the SSL server is implemented, things can become a bit more complicated. Boost.asio has an example of SSL server that you can find in Boost/libs/asio/example/ssl/server.cpp.
Windows features for Boost.asiothe next feature is only implemented in the Windows operating system
Stream ProcessingBoost.asio allows you to create footprints on a Windows handle so that you can use most of the free functions, such as read (), Read_until (), write (), Async_read (), Async_read_ Until () and Async_write (). Here's how to read one line from a file:
HANDLE file =:: CreateFile ("Readme.txt", Generic_read, 0, 0, open_always, File_attribute_normal | file_flag_overlapped, 0);
Windows::stream_handle h (service, file); Streambuf buf; int bytes = Read_until (h, buf, ' \ n '); Std::istream in (&BUF);
Std::string line; Std::getline (in, line); Std::cout << line << Std::endl;
The Stream_handle class is only valid if the I/O completion processing port is in use (this is the default). If the situation is met, Boost_asio_has_windows_stream_handle is defined
Random access handleBoost.asio allows random reads and writes to a handle to a normal file. Similarly, you create a wrapper over the handle and then use the free function, such as READ_AT (), Write_at (), Async_read_at (), Async_write_at (). To read 50 bytes from 1000 of places, you need to use the following code snippet:
HANDLE file =:: CreateFile ("Readme.txt", Generic_read, 0, 0, open_always, File_attribute_normal | file_flag_overlapped, 0);
Windows::random_access_handle h (service, file); Char buf[50]; int bytes = Read_at (h, +, buffer (BUF)); std::string msg (buf, bytes);
Std::cout << msg << Std::endl;
for Boost.asio, random access handles provide random access only, and you cannot use them as flow handles. In other words, free functions, such as read (), Read_until (), write (), and their relative async methods, cannot be used on a random-access handle. The Random_access_handle class is only valid if the I/O completion processing port is in use (this is the default). If the situation is met, Boost_asio_has_windows_random_access_handle is defined
Object HandleYou can wait for core objects through Windows handles, such as modify notifications, console input, events, memory resource notifications, processes, semaphores, threads, or timers that can wait. Or simply, all you can call WaitForSingleObject stuff. You can create a Object_handle package on top of them, using wait () or async_wait ():
void On_wait_complete (Boost::system::error_code err) {} ... HANDLE evt =:: CreateEvent (0, True, true, 0); Windows::object_handle h (service, EVT);
Synchronous wait h.wait (); Asynchronously waits for h.async_wait (on_wait_complete);
Boost.asio POSIX featuresThese features are only available on Unix operating systems
Local SocketBoost.asio provides basic support for a local socket (known as the UNIX domain socket). A local socket is a socket that can only be accessed by an app running on the host. You can use a local socket for simple interprocess communication. You can connect both ends in a client or server way. For a local socket, the endpoint is a file, such as/tmp/whatever. The cool thing is that you can grant permissions to the specified file, thereby preventing the specified user on the machine from creating a socket on the file. You can connect using a client socket, such as the following code snippet:
Local::stream_protocol::endpoint EP ("/tmp/my_cool_app"); Local::stream_protocol::socket sock (service); Sock.connect (EP);
You can create a service-side socket, such as the following code snippet:
:: Unlink ("/tmp/my_cool_app"); Local::stream_protocol::endpoint EP ("/tmp/my_cool_app"); Local::stream_protocol::acceptor Acceptor (service, EP); Local::stream_protocol::socket sock (service); Acceptor.accept (sock);
as long as the socket is created successfully, you can use it like a normal socket, which has the same member method as the other socket classes, and you can use it in the free function that uses the socket. Note that local sockets are available only when the target operating system supports them, that is, boost_asio_has_local_sockets (if defined)
connect a local socketEventually, you can connect two sockets, either non-connected (datagrams), or based on a connection (stream):
Based on the connection local::stream_protocol::socket S1 (service); Local::stream_protocol::socket S2 (service); Local::connect_pair (s1, S2); Data Report Local::d atagram_protocol::socket S1 (service); Local::d atagram_protocol::socket S2 (service); Local::connect_pair (s1, S2);
internally, Connect_pair uses the POSIX Socketpair () method that is not very well known. Basically what it does is to connect two sockets without a complex socket creation process, just one line of code. This was used in the past to implement inter-thread communication. In modern programming, you need to avoid it, and then you'll find it useful when dealing with legacy code that uses the socket.
POSIX file descriptorBoost.asio allows synchronous and asynchronous operations on some POSIX file descriptors, such as pipelines, standard I/O, and other devices (but not on different files). Once you have created a Stream_descriptor instance for such a POSIX file descriptor, you can use some of the free functions provided by Boost.asio. such as read (), Read_until (), write (), Async_read (), Async_read_until (), and Async_write (). The following shows you how to read a line from stdin to output to stdout:
size_t Read_up_to_enter (error_code err, size_t bytes) {...} Posix::stream_descriptor in (service,::d up (Stdin_fileno)); Posix::stream_descriptor Out (service,::d up (Stdout_fileno)); Char buff[512];
int bytes = Read (in, buffer (buff), read_up_to_enter); Write (out, buffer (buff, bytes));
The Stream_descriptor class is valid only if the target operating system supports it, that is, boost_asio_has_posix_stream_descriptor (if defined)
ForkBoost.asio supports programs that use the fork () system call. You need to tell the Io_service instance when the fork () method will occur and when it happens. Refer to the following code snippet:
Service.notify_fork (io_service::fork_prepare); if (fork () = = 0) {
Child Service.notify_fork (io_service::fork_child); ...
} else { //Father
Service.notify_fork (io_service::fork_parent);
... }
It is recommended to use the service that will be called on different threads, although Boost.asio allows it, I strongly recommend that you use multi-threading, because using Boost::thread is a piece of cake.
Summaryfight to make your code simple and clear. Learn and use the process. This will allow you to minimize the debugging effort, but only if there are potential bugs in the code, Boost.asio will lend a helping hand, as we have seen in the debugging chapters. If you need to use Ssl,boost.asio to allow basic SSL encodingUltimately, if you know that your application is for a dedicated operating system, you can enjoy the features that Boost.asio has prepared for that particular operating system. network programming is very important at the moment. Boost.asio is a must-learn content for any 21st century C + + programmer. We also have a deep understanding of the theory and then put it into practice, as a reference and as a collection of portable Boost.asio examples, because you can read, test, understand, and expand very simply. It is a great pleasure to read this book. Also hope that programming is a great pleasure.
Boost.asio C + + Network programming Translator (30) [end]