This part of tutorials all we've discussed were buffers and I/O operations. That might have seemed boring and over-detailed. However that had to be done in such details. We had to eat this frog. Networking is all about I/O after all.
We've covered all major aspects of Boost.Asio by this point. Now you know how to write both client and server applications. How to resolve hostnames, accept connections and initiate connections on your own. How to fuse Boost.Asio I/O and third party event polling. How to write multithreaded Boost.Asio application and synchronize its control flow.
Correct and accurate work with I/O functions is one of the most important thing. That's why we spent so much time learning them in details. Let me explain why it's so important.
Most of the server applications are intended to work with internet users. Yes, there are some applications and services operating inside LAN or even just one local machine. However most of the time you white a server to serve users from the internet.
When you write both client and server applications, you have to come up with a set of rules on how will you transmit a data between them. Since you can't just send C++ class instances through a socket, you have to serialize them into byte sequence on one side and deserialize them back into objects on the other side. Just like if you want to save an instance of
std::vector into a file today and then read it back from the file into
A set of rules on how you transmit a data is called “protocol”. For example, it could be something like “The first byte is message type, the second two bytes are message length and let's call it N, and then goes N bytes which are the message itself”.
When you implement both sides — sending a data and receiving of it — everything seems simple and under control. However putting your server application into the internet is something entirely different. Since that moment anybody in the whole world can connect to your application and send to it whatever they want! When dealing with your own code, sometimes you can skip some checks just because it's your own code and you know how does it work. However dealing with the data from the internet users, you have to verify everything, just everything! And that's why:
- Some of them could use an older version of your client application which operates on an older version of your protocol. So, those clients will transmit data in a different way;
- Some of them are bots scanning different ports and checking for different protocols supported by the server. There are myriads of different bots over the internet and they annoy every application which waits for the incoming connections;
- There are also enormous amount of mom's hackers who will connect to your server and try to hack it intentionally by sending different data and analyzing what your server do or respond back on that data!
So, any misstep, any unverified condition may lead to the unpredictable behavior. Your application may just respond with an ill-formed response. Or it may crash. Or it may corrupt valuable data. Or the hacker may gain an access to some sensitive information: user's private messages, bank cards info, etc. Or he could even gain full control over your server machine. Just because you forgot to verify a value of a single byte in your server application.
That's why dealing with I/O is so important and that's why we've talked about nothing but buffers and I/O functions in this part of lessons.
So, we've looked across most parts of Boost.Asio so far. In the next part of lessons we will finally start to talk about network application design principles — how to write production-quality applications with respect to security, performance and software design best practices.