diff --git a/_drafts/about_sockets.md b/_drafts/about_sockets.md new file mode 100644 index 0000000..143e47b --- /dev/null +++ b/_drafts/about_sockets.md @@ -0,0 +1,52 @@ +--- +category: technology +title: About Sockets +tags: +- networking +- linux +- programming +--- +A 'socket' is an abstraction for a network connection. Each machine has a socket it is communicating with; from an application's perspective, sockets make it possible to treat a network connection like a file, and simply read()/write() on it. + + + +Here is an overview of the lifecycle of a TCP socket: + +Establishing a connection + +An application on one system creates a socket and then calls bind(), listen(), and accept() -> this creates a socket in the LISTEN state. The socket will stay in the LISTEN state (and the accept() call will block) until an incoming connection is made on that port. + +On another system, an application creates a socket and calls connect(), passing it the address of the first system. This creates a client-side socket, which starts in SYN_SENT. + +Once these two sockets 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 + +At this point the applications can simply read() and write() to the socket. Each application will read() what the other application write()s. + + + +Shutting down the connection + +When one side of the connection calls close() on its socket, it sends a packet telling the other end it is finished (a FIN packet), and the socket *that sent the FIN* changes to FIN_WAIT. + +When a connection *receives* a FIN, it changes to the CLOSE_WAIT state. + +When a socket in FIN_WAIT receives a FIN, it closes. + +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. + + + + + +Now, 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)? + +When you try to read() on a socket the other side has close()d, you get EOF (the end of file marker). It is considered correct programming to, at this point, do any necessary clean-up work and call close() on your own socket. + +Otherwise you end up with sockets is CLOSE_WAIT. + +In other words, if a socket is stuck in CLOSE_WAIT, it is necessarily a fault in the application - the application is failing to check for the connection closing, and thus never calls close(). + +This problem is common in applications that do nothing but write() to their sockets (they never read() so they never detect the EOF).