Working With TCP Sockets

Working With TCP Sockets

Language: English

Pages: 125


Format: PDF / Kindle (mobi) / ePub

Do you know how your web server opens a socket, binds to an address, and accepts a connection?

I did a lot of web programming before I had enough knowledge to dig in and figure this stuff out.

I knew that other developers had a better grasp on the full stack than I did, but diving deep under the hood is one of the things that really made me a better developer all around.

I recently read a great thread that asked "What did the really successful programmers do differently?". This response really caught my eye:

> Be ready, willing, & able to deep dive multiple levels at any time. You must know what's going on under the hood. There is a strong correlation between "number of levels of deepness understood" and "programming prowess".

In this book I'll teach you these fundamentals using Ruby. I'll start with the fundamentals that are portable to any environment. Then I'll show you the beautiful abstractions that Ruby has layered on top of them.

Learning this stuff doesn't just apply to Ruby, or any other language. Every modern programming language has support for networking. Every language has their own way of doing things. But all modern languages support the Berkeley Sockets API. Ruby is no exception. There's certainly plenty of syntactic sugar, but below the sugar you can use the same Sockets API that you would in C, Java, Python, whatever. This is portable knowledge that will serve you for many years to come.

What you'll learn:

* The steps in the lifecycle of servers and clients.
* The various ways that we can read and write data in Ruby, and when they're appropriate.
* All the things you were never quite sure about: EOF, listen queues, TCPNODELAY, and tons more.
* The low level methods required for constructing sockets, as well as the syntactic sugar that Ruby provides.
* Known methods that will help you improve socket performance.
* Basics of SSL sockets.
* Should you write a lot of data at once or chunk it into smaller writes?
* Get comfortable with the socket programming API that's available in any modern programming language.
* More example code than you shake a stick at!
* A look at 6 different architecture patterns for building concurrency into your network programs.
* A closer look at a few different protocols: FTP and Redis.
* Multiplexing connections, non-blocking IO, socket timeouts, socket options, and more...

Operating Systems: A Concept Based Approach

HCI Beyond the GUI: Design for Haptic, Speech, Olfactory, and Other Nontraditional Interfaces (Interactive Technologies)

Haptic Interaction with Deformable Objects: Modelling VR Systems for Textiles (Springer Series on Touch and Haptic Systems)

The Master Algorithm: How the Quest for the Ultimate Learning Machine Will Remake Our World













Behaviour: $ nc -l localhost 4481 Then we'll boot up this client that makes use of write_nonblock: # ./code/snippets/write_nonblock.rbrequire 'socket' client ='localhost', 4481) payload = 'Lorem ipsum' * 10_000 written = client.write_nonblock(payload) written < payload.size #=> true When I run those two programs against each other, I routinely see true being printed out from the client side. In other words it's returning an Integer that's less than the full size of the.

The 220 response is a protocol implementation detail. FTP requires us to say 'hi' after accepting a new client connection. The last bit here is the initialization of a CommandHandler for this connection. This class encapsulates the current state (current working directory) of the server on a per-connection basis. We'll feed the incoming requests to the handler object and get back the proper responses. This bit of code is the concurrency blocker in this pattern. Because the server does not.

All be running inside the same interpreter. Even when using multiple threads MRI prevents them from achieving true parallelism. This isn't true in alternate Ruby implementations like JRuby or Rubinius 2.0. Processes don't have this issue because each time a copy is made, the new process also gets its own copy of the Ruby interpreter, hence there's no global lock. In MRI, only processes offer true concurrency. One more thing about parallelism and threads. Even though MRI uses a global.

One socket at a time. By marrying each active socket to a specific port number a host is able to support thousands of sockets concurrently. Which port number should I use? This problem is solved not with DNS, but with a list of well-defined port numbers. For example, HTTP communication happens on port 80 by default, FTP communication on port 21. There is actually an organization responsible for maintaining this list. More on port numbers in the next chapter. Creating Your.

Connection; it needs to monitor it for new requests and process those as well. It does this with an Evented reactor. When a new request arrives for a previously kept alive connection, that request is again queued up to the Thread Pool for handling. So Puma's request handling is always done by a pool of threads. This is supported by a reactor that monitors any persistent connections. Again, Puma is full of other optimizations, but at its core it's built on a hybrid of the patterns from the last.

Download sample