99% of developers don't get sockets. What actually is a socket? You've probably seen this kind of socket, but I'm referring to a completely different kind of socket in the software industry or computer science universe. We simply do not give justice to certain concepts like sockets, anonymous pipes, ephemeral ports, file descriptors, etc. These concepts end up being amorphous handwavy constructs in most developers minds. And there is a whole host of additional concepts and jargon that are not taught in nearly enough detail and that needs to be addressed. So in this video, I'm going to explain to you exactly what you need to know about sockets and give you an introductory taste of what sockets are. So the next time someone asks you, hey, could you explain to me what a socket is, how does TCP or UDP leverage sockets, and what layer of the OSI model do sockets operate in? You won't be drawing a blank. We should always start with a concrete answer to the question of what are sockets? At their core, sockets are an abstraction provided by operating systems to enable communication between different processes either on the same machine or over a network. They act as endpoints in a two-way communication channel. So when two machines or two applications need to talk to each other over the internet or a local network, each side of that communication will create a socket. And a socket is essentially a software construct that wraps a combination of a protocol, so TCP or UDP, an IP address, and a port number. The operating system uses this combination to route messages appropriately. You can think of it like a telephone. A socket is the phone, and the IP address and port together are like the phone number and extension. The two parties must dial each other correctly in order to establish a connection. But perhaps you've heard of the OSI model, but you're curious where do sockets fit inside that model. So to understand sockets in context, you should place them in the OSI model, which is a conceptual framework for how network systems communicate. Sockets operate primarily at the transport layer or layer 4 of the OSI model. The application layer or layer 7 like your web browser or a back-end service calls down to the socket API asking it to send or receive data. The socket then wraps the data into TCP or UDP segments, adds some headers and sends it to the network layer or layer 3 which deals with the IP routing. Sockets thus provide a clean interface between application logic and the underlying network stack and shields developers from the complexities of routing, packet fragmentation, retransmission, etc. Okay, but before you fully understand sockets, you have to realize that there are TCP and UDP sockets and these are the two main types of sockets. TCP or transmission control protocol sockets are connectionoriented and provide reliable ordered and error checked data transmission. Before data is sent, a three-way handshake is performed to establish the connection involving the exchange of SIN and ACT packets. This guarantees that both sides are ready and TCP ensures that packets will arrive in order and without duplication which makes it ideal for applications like web browsing, database access or file transfers. UDP or user datagramgram protocol on the other hand is connectionless and unreliable. It simply sends datagramgrams to the target IP and port without any handshake. There's no guarantee of delivery, ordering, or integrity. However, it's much faster and much more lightweight as a result, which makes it ideal for real-time applications like video streaming where speed is prioritized over reliability. If you are interested in taking your software engineering skills to the next level, I would encourage you to build projects. I'm not talking about going down the rabbit hole of tutorial hell and building a to-do list, calculator, or weather app. I'm talking about building complex real world projects beyond the basics. And this is where Code Crafters comes in. This platform provides interactive tools to build developer tooling from scratch. There are a number of courses that teach building git from scratch, building an in-memory reddus database, an HTTP web server, your own Docker, your own DNS server, and many others. I personally love that there is built-in support for over 20 different languages. My favorite, of course, is Golang, but I would highly recommend trying a newer language like Zigg as well. I'm excited to announce that I'm partnering with Code Crafters to offer all my viewers a 40% off. For more details, you can find a link in the description down below as well as the pinned comment. Okay, but when we talk about the socket life cycle, we still don't fully understand the server perspective as well as the client perspective. On the server side, sockets follow a specific life cycle. It starts with the creation of a listening socket, which is bound to a specific IP address and port. This socket doesn't engage in communication directly, but instead waits for incoming client connections. Once a client initiates a connection, the server accepts it, creating a new socket instance that's dedicated to that specific client, and the original socket continues listening for new requests. This new socket becomes the channel through which all communication with that specific client occurs. And this enables a server to handle many different clients concurrently, each with its own socket. In synchronous setups, this is typically handled with multi-threading or multipprocessing where each client connection is managed by a separate thread or process. This model is straightforward and works well for a small number of connections, but it does not scale efficiently. Each thread consumes memory and incurs context switching overhead. And as the number of concurrent sockets grows, the performance quickly degrades due to contention and resource exhaustion. In high performance systems like real-time APIs, message brokers, or multiplayer game servers, this limitation is addressed using techniques like non-blocking IO or eventdriven architectures. These approaches allow a single thread or a small number of threads to manage thousands of open sockets concurrently. This is achieved using system calls such as select, pull or even more scalable alternatives like e- pole on Linux or KQ on BSD or Mac OS which notify the application only when specific sockets are ready for reading or writing. These event notification mechanisms drastically reduce CPU usage and latency by avoiding idle waiting or redundant pulling making them the foundation of frameworks such as Engine X, Node.js, and Async.io. The client creates a socket and initiates a connection to the server's IP and port. If using TCP, this initiates the three-way handshake. Once connected, the client can write to and read from the socket just like working with a file. In fact, on Unix like systems, sockets are treated as file descriptors, meaning they can be used with common system calls like read and write. And if you want a reminder of what a file descriptor is, essentially when you open a file, the OS creates an entry to represent that file and store the information about that open file. So if there are 100 files open in your OS, then there will be 100 corresponding entries in the OS somewhere in the kernel. And these entries are represented by integers like 100, 101, 102, 103. And this entry number is the file descriptor. So really, it's just an integer that uniquely represents an open file for the process. If your process opens 10 files, then your process table will have 10 entries for file descriptors. Very similarly, when you open a network socket, it's also represented by an integer. In this case, a socket descriptor. After the communication ends, both the client and the server are expected to close the socket to free up system resources and prevent memory leaks. Any improperly closed sockets can lead to resource exhaustion, especially on busy servers. There's also some interesting quirks around socket internals and states. So for TCP sockets, the system maintains a state machine for each connection. There's some common states such as listen, sin sent, sin received, established, fin weight one, time weight, and close weight. And these states represent various phases of the connection setup, maintenance, and tear down. For instance, the time weight state ensures that delayed packets from an old connection are not misinterpreted as being part of a new one. And knowledge of these states is critical in diagnosing issues like port exhaustion or socket leaks which often plag longived servers or high concurrency applications. But how does the operating system actually deal with port number and socket uniqueness? Every socket is uniquely identified by a five tuple protocol, source IP, source port, destination IP, and destination port. And this combination allows the OS to distinguish between multiple simultaneous connections, even if they are all talking to the same remote server and port. For example, multiple browser tabs connecting to example.com443 will each have a unique source port assigned by the OS, which allows the server and the client to differentiate between those sessions. This mechanism is what enables one computer to have hundreds of open connections to different or even the same remote services. While most socket discussions focus on network communication, for example, TCP or UDP over IP, there is another important type known as Unix domain sockets or UDS. These are not network sockets. They are used for interprocess communication or IPC on the same host. So instead of using an IP address and port, UDS uses a file path on the file system. For example, /temp/app.sock as the address. They are much faster than network sockets since they bypass the network stack entirely and don't require any IP routing or protocol overhead. There's applications that you're probably very familiar with like Postgress SQL or Reddus that often default to UDS for local client server communication when performance and security are critical. But something that's very important to note is that sockets are inherently insecure. And this is because they transmit raw data unless explicitly encrypted. Secure communication over sockets is usually achieved via transport layer security or TLS. TLS wraps an existing socket connection and ensures that all data sent over it is encrypted and authenticated. In Python, for example, the SSL module provides functionality to wrap a plain socket in TLS. And this is very important for applications transmitting sensitive information like passwords, financial transactions, private user data, etc. Any raw or misconfigured sockets that do not use TLS can become targets for man-in-the-middle attacks or packet sniffing. But how often are sockets actually used in distributed systems and microservices? Well, as you may have guessed, in these modern software architectures, especially in microservices and distributed systems, socket-based communication is absolutely everywhere. Restful APIs over HTTP which uses TCP sockets and gRPC over HTTP2 which is also TCP based are very popular protocols for serviceto-service communication. Load balancers like EngineX or Envoy and service meshes like ISTTO manage socket level routing and traffic shaping. In high performance systems, developers sometimes implement custom binary protocols over raw TCP or UDP sockets for ultra low latency communication. Technologies like CFKA, Reddus, and Cassandra all use sockets under the hood to distribute data across nodes. There's a very clear reason why you should at least be able to articulate what a socket is. Sockets are truly the foundation of modern worked computing. Every time you load a web page, stream a video, send an email, or interact with a mobile app, sockets are involved in transmitting the data across the wire. As a developer, having a deep understanding of how sockets work gives you control over network communication performance and security. It also enables you to build scalable back-end systems, troubleshoot complex issues, and optimize communication protocols. Having a solid grasp of sockets is going to be a major asset for you. If you learned something new in this video, please give this video a thumbs up and hit the subscribe button and turn on all notifications if you want to be notified for future updates. As always, thank you very much for watching this video and happy coding.