So let's start talking about Network Programming in a little bit more detail, and let's start looking at these specific APIs that we use to write network applications. In particular, let's go through how a web browser is written as a motivating example. So when we talk about network APIs, there's a certain similar API that was invented back in the '80s which had a huge impact on how we write network applications. In particular, this API is called the Sockets API. The Sockets API structures communication in a certain way. Its structure is that in a way such that it's similar to phone calls. If you want to make a phone call to somebody, what you do is you pick up your phone and you dial a phone number then it connects, and then you have a logical connection that's open. It's an intuitive way about how you can communicate, and the Sockets API was kind of inspired by that. With the Sockets API, you don't dial a phone number, but you can do is you can put in the IP address to a network interface. Then you create a connection. Then you have a handle onto that connection, and that handle is called a socket. So the whole idea behind the Sockets API is to create these connections that have handles into them, and that you can refer to the handles and data over the handle and things like that. The Sockets API was introduced in 1981 by BSD Unix, and it's a very important interface, it's something that had a huge impact on the way we write all sorts of APIs. If you've program to Bluetooth or Zigbee, you're going to be using the Sockets API. Is not going to be the same as they did back in the '80s, is going to be more object-oriented and there'll be different variations on it. But if you understand the classic Sockets API, you're going to know how to program in these different interfaces. The Sockets API is implemented as a library and a set of system calls, and it provides similar interfaces for different protocols. If you want to do TCP or UDP or SCTP or any transport, you don't have to worry about all the details of the mechanics, with the Sockets API abstracts away all that. It presents these interfaces where you kind of send data to a socket, and you don't have to worry about all the details of TCP and UDP. So the way it looks like this. You write your network application, and then your network application calls a set of system libraries. These system libraries do things like allow you to send data, open connections, and things like that. The system libraries exist a top a system call interface. Then the system call interface sits the top kind of these other structures inside the kernel. There's this layered structure for writing data to your hard drive to different file systems. There's a set of layers for communicating over the network, and a set of layers for communicating with memory and so on. So this is the overall structure of your kernel. You have applications and they call libraries which in turn call system calls which are inside the kernel, and then everything below that is inside the kernel. You have device drivers and then layers of abstraction which hide details of individual devices, and the same is true for network device drivers. So the blue area is the network stack, and then there is libraries on top of that. This is known as the Sockets API. So the designers of the Sockets API had to answer this question, how should we design it? If you design an API, you got to really think carefully about what information you want to expose, what should the functions look like, what sort of structure should you have the user work with? Because if you have an intuitive API can make programming so much easier. So the way the Sockets API was constructed is there's a few different functions. First of all, there's data structures. There's new data structures that store information about connections and hosts. So you don't have to worry about details of bits, just working with bits, there's higher-layer structures. We can represent a host or a name or an IP address and you can work with those. So for example, there structures to hold IP addresses, important information, socket numbers, things like that. There's also functions to establish logical connections and tear down connections. So if you're any TCP for example, TCP is all about reliability in establishing connections that persist over time, and there's functions in the Socket API to do that. There's functions to maintain the socket numbers, and associate socket numbers with network addresses, and establish connections. There's also functions to send and receive data as well. You can take a socket and then send data into that socket and received data out of that socket. To show you how these functions work in practice, I'm going to show you an example sockets program. This program is written in the traditional BSD style Socket API interface. But if you understand this interface, you'll know how to program to Bluetooth and all these other different interfaces because they do the same thing. There's different language specific stuff, but the overall structure of how you call these functions is exactly the same. So the first thing we're going to do is we're going to create a socket. The socket is a descriptor. It's an index into the kernel, where the kernel has a list of connections, and the socket descriptor is a pointer into that list. So you can have a bunch of connections open and then your program can refer to a specific connection using that number. There's also a host int structure which is used to store information about the domain name, you could also store a list of addresses. So then there's some other code and then a little bit lower there's a function to do a DNS lookup. So this is super handy. If you're writing an application, you don't want to make your own DNS request. Imagine if you have to do that, fabricated DNS requests send it off and wait for responses and redo that, that's all programming inside the operating system, you don't have to worry about that. Just do a single function call, pass in the URL, pass in the domain name that you want to reach, and you'll get an IP address back. Then what we do is we get an available socket for the operating system, because we don't know what sockets are available. So here what we're doing is we're asking the kernel, ''Hey, you have a table, you've launched sockets that are open? Give me an unused socket descriptor that I can use.'' So you get that. Then the next thing you're going to do is you're going to create an address structure where you're going to store information about the host you want to connect to, and you're going to fill in what you know. You don't know the MAC address, but you do know the IP address because you just did a DNS lookup. You know the port that you want to connect to. So you're going to fill that in this structure, and then you're going to tell the kernel, ''I would like to connect, I would like to take this socket descriptor and open a logical connection to that other host,'' and then create that connection, leave it open, and then it'll be connected. Then what I can do is I can send and receive. So here this function sends using that socket descriptor a string, it sends a GET request. Then what I can do is I can send and receive and all those things, and then when I'm done, I can close the socket descriptor. So this is an example of how you write a sockets program for a client. The way you write a sockets program for a server is actually pretty similar. The difference is you create a socket and you bind it to a local port, and that tells the operating system to create that socket and leave it open, so when someone connects, it will unblock you and then you'll be able to send and receive. So it's very similar, and you can look up the examples online of how to do this.