In the last few chapters, you learned how to apply process-based concurrency to a practical use case. Now, we’re ready to take on one of the essential problems of systems programming: writing a server. Servers have a fundamental difference from all the programs we’ve written so far. Although they provide a variety of capabilities, their behavior is driven not by any preset sequence of commands but instead by reaction to unpredictable external events. Because of this, writing servers isn’t easy. However, if you accept the challenge, you’ll learn how to write programs that are far more robust in their interactions with the outside world.
In this chapter, and those that follow in Part II, we’ll build a usable and performant web server from the ground up. We’ll start with a minimal TCP socket server and become familiar with the fundamental OS facilities used by all servers. We’ll then reuse our parsing code from Chapter 3, Writing a Simple HTTP Client, to construct a working HTTP server and perform a stress test to measure the results. With data in hand, we can then better understand the capabilities and limitations of our code, pointing the way toward the high-performance asynchronous techniques we’ll look at in chapters ahead.