From e6d07f70fb767cd1eecdff68bed55f44a74f8fa0 Mon Sep 17 00:00:00 2001 From: Anna Wiggins Date: Wed, 4 May 2016 23:52:45 -0400 Subject: [PATCH] Minor formatting changes. --- .../technology/2016-05-04-sockets-close-wait-and-you.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_posts/technology/2016-05-04-sockets-close-wait-and-you.md b/_posts/technology/2016-05-04-sockets-close-wait-and-you.md index 31d9caf..e9c8e5f 100644 --- a/_posts/technology/2016-05-04-sockets-close-wait-and-you.md +++ b/_posts/technology/2016-05-04-sockets-close-wait-and-you.md @@ -14,7 +14,7 @@ There are two categories of people who might want to know more about how sockets Here is an overview of the lifecycle of a TCP socket: -## Establishing a connection +### Establishing a connection An application on one system (we'll call it the "server") creates a socket. In C1, this is done by calling `socket()`, `bind()`, and then `listen()`. This creates a socket in the LISTEN state. To actually accept an incoming connection, the program also needs to call `accept()`. The socket will stay in the LISTEN state (and the accept() call will block) until an incoming connection is made on the port specified by the program. In the `bind()` call, the program specifies a port number use. @@ -22,13 +22,13 @@ On another system, (the "client") an application creates a socket (with `socket( Once these two sockets (one on each system!) start talking, they go through a '3-way handshake' (transparent to the application) to establish some necessary metadata, and then both sockets change to the ESTABLISHED state. -## Sending data +### Sending data At this point the applications can simply `read()` and `write()` to the socket. Each application will `read()` what the other application `write()`s. If either system goes for a while without sending any data, the system on the other side of the connection will send a "keepalive" packet. This is a packet with no data in it that only exists to make sure the other side is still there. As long as both sides keep sending/responding to data and/or keepalives, the sockets will stay in the ESTABLISHED state. -## Shutting down the connection +### Shutting down the connection When one side of the connection calls `close()` on its socket, it sends a special packet telling the other end it is finished (a FIN packet), and the socket that sent the FIN changes to FIN_WAIT. @@ -38,7 +38,7 @@ When a socket that's already in FIN_WAIT receives a FIN, it closes. It will also A socket in CLOSE_WAIT, by contrast, cannot close *until the application calls `close()` on the socket*. Once this happens, the system sends a FIN so that the remote end can finish closing, and the socket closes. The important takeaway from this is that if you see sockets stuck in CLOSE_WAIT indefinitely, that's a bug in the application that opened the socket. -# Preventing indefinite CLOSE_WAIT +## Preventing indefinite CLOSE_WAIT From an application's perspective, all of these socket states are transparent; they are a kernel abstraction. The application just has a file descriptor that it is writing and reading on. So how do we detect when the other side has closed down the connection? (i.e. that we are in CLOSE_WAIT)