Minor formatting changes.

This commit is contained in:
Anna Rose 2016-05-04 23:52:45 -04:00
parent 4e6c13901e
commit e6d07f70fb

View File

@ -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: 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 C<sup>1</sup>, 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. An application on one system (we'll call it the "server") creates a socket. In C<sup>1</sup>, 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. 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. 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. 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. 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. 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) 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)