 Hello and welcome in this video We're going to get Python installed on our computers, and I just want to walk you through that process in case you don't have that there Just to make sure everybody is on the same page So if we go to our web browser, and we simply just type in Python up in the search bar Probably the first link here Python.org. We're gonna click downloads And as of the time of recording this video the current version of Python is Python version 3.10.6 So I'm going to click the download button and that's going to download an exe for me right here so I'll click that to open this up and Pretty much we're going to leave everything the same except I'm going to make a special note here to check the box It says add Python 3.10 to our system path variable and now that's that that that is there I'm just going to do the the default install so I'll click install now Allow this to save changes and that's going to go through and do its installation here And I will pause the video and come back when it's done Okay, so it looks like that has Fully installed here, so I'm just going to close out here and let's just verify a couple of ways we can verify it First if I open up a command line or a power shell if I simply type in the word Python here I should be given the Python interpreter so I can do things like you know print Hello world and that should work fine. Awesome. So Python is installed and it gives us our version 3.10.6 And then you know just one more thing here if you go to your programs if you search Idol or IDLE this is like the You know installed Python IDE that's included here, so this is installed here and again we can type things you know like print hello world And that should work out fine You know and you can create new files and then write your scripts and then save them and run them We're gonna use a different IDE here in this video. There's nothing wrong with idle. I just like Some other options a little bit better, and so we'll see how to install those in our next video. I'll see you then Okay, in our last video we installed Python got that set up on our computer So in this video, we're going to install the IDE that I'm going to use for all of the videos here Of course, you can use whatever IDE you want I just like to use Microsoft Visual Studio code or VS code So I'm gonna just type into Google Microsoft Visual Studio code And I'll click the download link right here for us And that'll bring me to the option to download it for whatever specific platform. I'm on so I'm on Windows So I'll click download here, and that should launch the download will download that exe And then once it's downloaded we'll launch it and just look at some of the options We have for configuration of the install. All right, so just a couple seconds left All right, so it looks like that exe has downloaded. I'll click it to launch it and We'll read we should probably read through this agreement and we'll speed read it and click accept Like we do for most of those things I think the default folder is perfectly fine here, and we'll create a shortcut great here. I'm gonna leave everything the same I'm gonna definitely make sure I add this to our path variable and so I'll click next and I will click install. All right, so I'm gonna let it do do its thing I'll pause the video and unpause it when the install has complete Okay, so our download has completed so I'm just gonna click finish here, and that should launch VS code for us All right, perfect. So here we are One of the first things that we're gonna do is I'll just close this tab over here on the left We have like our file explorer and search right here at the bottom. We have some extensions We're gonna go to our extensions You may have some pre-installed you may not but the first thing I'm gonna do is I'm gonna search the extension marketplace I'm gonna search for Python And this first one that comes up here We're gonna install Python. It's got right now. It's got six point sixty one point six million downloads. That's crazy So I'll click install here This will install a Python extension for us so that we can bring in that functionality into VS code So hopefully that won't take too long and then what we'll do is we'll just create a new file To try to verify that everything is working properly. All right, so this is installing Why don't I pause the video and we'll come back when that's done? Okay, perfect. So it looks like that is installed. So if I just click if I you know Remove this and I look at what I have installed. You can see it installed Python and Pylance for me. So now I'm just gonna create come over here I'm gonna do a new file and we'll select it to be a Python file All right Says Python is not installed that might just be because I had to restart my computer and I didn't do it We'll check that first thing that I'm doing is I'm just gonna save this file I'm just gonna save it to my desktop right now. I'll call it test dot PY I'll give it the dot PY Python extension I want to get rid of my extensions here I just simply click that box to get full screen and here we'll do print hello world And so let's see if this runs so we'll do run and we'll run without debugging You can do that with control at five if you like And right down here in the terminal it looks like everything is working out nicely So we're we're printing hello world to our terminal here So our IDE VS code is installed and we are good to go So I will see you in our next video Hello in this video I just want to give a brief introduction to some of the networking concepts that we're gonna sort of focus on Through the scope of these videos So I want everybody to have just a firm understanding of some of the basics before we dive into writing some Python network Applications with sockets so we have to know a little bit about you know the internet And so what exactly is the internet well? We can say the internet's a global network of billions of electronic devices all connected together Essentially, it's one huge network that is made up of various smaller networks, right? If you think about it at your house, you probably have your own network your Wi-Fi network Maybe you've connected to and your neighbor has a Wi-Fi network and your other neighbor has a Wi-Fi network And your work has a network and your maybe your school has a network and all these networks come together to create the internet Now all of the machines on the internet are either what we call servers or clients So the machines that provide services to other machines These are known as servers and the machines that are used to connect to those servers are clients So like your laptop or your computer at your house that you use to like get on the internet and Google things That is going to be a client and when you are Googling something and you're asking for information what you're doing is you are connecting to a Google server somewhere And so a couple of really important questions that I think are going to drive the focus of these videos here is How do we distinguish one computer or device from another on a network? And how do we actually send information from one computer or device to another over? Over a given network and so these are the questions that are going to drive our discussion So first let's talk about a couple of different types of networks Because we said the internet's kind of one giant network that's made up of lots of smaller networks So the giant network we can refer to as a WAN or a wide area network It's a group of computers that spanned across a large scale Geographic area making what was essentially is a large scale network and the internet is a great example of a WAN because it spans, you know the whole globe Opposite of this is what we would call a LAN or a local area network This is a group of computers connected in a limited geographic area making a much smaller scale network So your home network that you connect to at your house or maybe your network at your school is a great example of a LAN or local area network Now if you are connected to the internet at your home We said the internet is a wide area network in order to get on that wide area network You are most likely paying an internet service provider for what's known as a public IP address This is a unique address on the internet and your router or modem that connects you to the internet is the only Device on the internet with this public IP address. It has to be unique Now inside of your home your computer Most likely has received what's known as a local IP address from your router now inside your home This is a unique IP address. So like your computer versus your maybe, you know You're another family members computer versus your cell phone versus your smart TV inside your house They will all have unique local IP addresses However on other networks or lands because we're inside of a home network now There can be other devices that have those same local IP addresses. So maybe on your neighbor's network There is their computer that has the exact same local IP address as your computer It doesn't matter because you're on different lands here now An important thing that we have to state is that you know, how do we determine these addresses? Well an internet protocol address or IP address is essentially the network address for your computer So the internet the WAN or your router a land knows where to send data essentially So here's a couple of examples like here's a good example of a public IP address 18.25.15.99 and you can actually type in public IP addresses and determine where that IP addresses are originated from So I did that for this one and this is coming from Cambridge, Massachusetts. It's well known now Here is a local IP address. This is my house and this is my laptop right now 192.168.1.7 This is my local address and so you have no idea where I am right now Just by looking at my local address because it's kind of locked off from the internet now The most common type of IP address is the IPv4 or internet protocol version 4 Address and IPv4 addresses consists of four numbers grouped together ranging from 0 to 255 So you see right here we have 192, 168, 1, and 7. Here you have 18, 25, 15, and 99 So we're following the internet protocol version 4 So IPv4 protocol and we need a protocol to give a common agreement on how Information will be shared and expressed so everything that we do in this course. We're gonna use IPv4 There's another protocol called IPv6, which is a little bit more advanced But for our purposes and mainly for the purposes of it everybody else everyone's a lot of people are still just using IPv4 So how can you find your own IP address? So this is an important thing we're gonna have to do so you're gonna want to open up You can open up a terminal or a CMD or a power shell depending on what device you're on or operating system And in Windows, it's as simple as typing IP config and I have a Windows computer. So we're gonna do that shortly on Linux you can type IP space a or This if you have what's called the I net I think it's I net tools packages installed You can type if config this used to be the primary way, but I think they're moving away from it and going to IP a On Mac. I'm not sure if this works. I don't have a Mac. I've never tested it but I Google searched it and I you can type IP config get if ADDR So get interface address and then Ian zero would be the name of the first interface that's on your device You might have to change just like Ian one Ian two and when I say interface I mean like the network interface the thing that's connecting to the computer So I'm just gonna back out a full screen here and I'm gonna open up a power shell And so here is my power shell and I'm on Windows. So if I want to see my current IP address I simply just type IP config and if we look here we get a lot of information so I am going to look I'm connected via Wi-Fi right here. So I'm going to look at my wireless adapter So here's my Wi-Fi adapter and we get some nice in information Here is my IPv4 address if you notice it is 192 dot 168 dot 1 dot 7 now we In my house, I've got lots of devices connected to my my Wi-Fi and In my house my laptop right here is the only one that is 192 dot 168 dot 1 dot 7 So I have my cell phone right next to me. What might its IP address be if it's connected to the same network? Well, I mean, I guess you could say it could be any number But there's an important thing right here called the subnet mask and we're not really gonna use subnet masks But I figured we would just talk about it the subnet masks kind of tells you what the actual network address is So if you look here in my subnet mask, I have 255 dot 255 dot 255 dot zero It's four numbers again and anywhere you have a 255 what that means is in your network address That number has to be the same. So I've got a 255 here and the first number So that means in my network address the first number has to be the same I've got a 255 is my second number so in my network address This number has to be the same a 255 here is my third number So in my network address that number has to be the same here. I have a zero So what that tells me is my last number of my network address can vary So, anything on my local network would have the IP address of 192.168.1 dot something else. So, the 7 will vary. So, maybe my cell phone is 192.168.1.8 or dot 9 or dot 10 or dot 11. Now, we have one more really important IP address right here and it's our default gateway. Essentially, this is going to be the local IP address of your router or modem. So, if you look here, we have 192.168.1. The network address has to be the same here. We've already indicated that and then typically your router or modem sits at dot 1 on the network connection. So, my router's IP here is 192.168.1 and my computer's local IP is 192.168.1.7. Now, be careful. These are what I'm calling my local IP address right. These are my local IP addresses. My public IP address. So, when I want to communicate, I connect to my router and my router actually has a public IP address that it uses to get to the internet. It gets information from the internet. The internet sends it back to my router and then my router sends it back to my local machine right here at this address. So, let's kind of maybe visualize this. I have a nice little graphic here that I think will maybe help explain this. So, imagine here, I've imagined everything on this side of this line is a house on a land, okay, on a local area network and everything above this line is another land and so we've got a couple of routers here that are connecting to the internet. Notice that the router is on the land, okay, it's on the local side, but it's also on the public side. It's connected to the internet in both cases. So, let's pretend this is my house. So, on my local network, my router has an IP of 192.168.1.1 that's our local IP address and that router can send information to all of the different computers connected to it. Computers have local IP addresses, 192.168.1.14, .7, .4, .13, .34. On my local area network, each IP is unique, so that looks perfect. So, if computer two wants to talk to computer one, computer two sends some information to the router with the IP address of who we want to talk to and the router routes it to this computer. Everything looks great. Look at my friend's house. So, this is my friend's house. We've got another local area network. My IP address, 192.168.1.1. That's absolutely fine because my LAN up here and my LAN down here are isolated. And so, we've got a couple of devices connected to this local area network. 192.168.1.5, 192.168.1.14. On this LAN, those IP addresses are unique. It doesn't matter that this local area, this local IP and this local IP are the same because they're on different LANs. Note though, the router also has a public IP address. 77.45.82.17 or 77.45.19.16. These are unique on the internet. So, let's say computer two on this LAN wants to talk to this computer on this LAN. How's it going to do it? Well, it sends its information to the router. The router then sends it to the internet, which sends it to a specific router, which then forwards it over to this machine. And this is kind of how our public and local IP addresses sort of work. And we're going to get more into this later on in the course. There's a lot more to this. There's certain things that we might have to do like set up static IP addresses or enable what is known as port forwarding. You might be looking here, and I've got a little star here that says our machine running our server on port 12345. So, we're going to have to talk a little bit about what exactly these port numbers are port addresses. And so, let's head to that right now. So, if you think of an IP address as the address of your computer on a given network, a port address is the address that a specific application or service runs on that given computer. So, I'm just going to come back here. Imagine computer two. The router is going to be sending a lot of information to computer two. Maybe the router is sending web traffic to computer two for a bunch of different websites. Or maybe it's going to be sending email information. Or maybe it's sending something known as file transfer protocol. We're going to be sending lots of different information to the computer. The computer has to sort through it. So, how does it sort through it? Well, it has port addresses. And each port address on a computer, there's certain information running. So, some common ports and services like port 21 typically runs what is called file transfer protocol, FTP. Port 22 typically runs SSH or secure shell. Port 25 is SMTP, simple mail transfer protocol. Port 80 and port 443, these are for web traffic. HTTP or HTTPS, hypertext transfer protocol and then hypertext transfer protocol secure. So, when your router is trying to send information, whether it's web traffic or an FTP request, it sends them to your specific computer, the IP address. But then it sends it to a specific port where we know a service is running. So, your router may receive data to send to your computer from a website or for a file transfer protocol using FTP. It will send it both to the respective IP address, but the web traffic will go to port 80 or port 443. Well, the FTP request will go to port 21. So, let's just take a quick look at some of our services that are currently running on my machine in my PowerShell using a command netstat, tac na. So, if I open up a PowerShell, I can type netstat. If I just type netstat, I think it's gonna give me a running list of some of the things that are connected. And right now, I don't really have anything connected. Here we go, 192.168.1.7, okay? So, that's my local IP address is currently connected to 52.159.127.243. And it says it's HTTPS traffic. So, this is not on my local network. This is probably on some public IP. And this is probably my Google Drive that I have open right here. And it's HTTPS, an HTTPS connection. And if you look here, I've got the lock. If I click here, it says connection is secure. So, I think that is probably my HTTPS right here. So, let's cancel this because I want to see some of the port services. So, to cancel inside of a terminal, you just hit control, control X, control C, control C, there we go. And so, now I'll type netstat, tac na. And so, here we get a long list of all of the things that are currently running. And so, if you look here, you notice there's protocol, local address, foreign address, and then the state. And so, I'm just gonna note here for the protocol, there's listed. We have TCP and then we have some UDP stuff going on here. So, we're gonna talk a little bit in a second about TCP and UDP. But let's just note like some of these connections that are happening right in here. And so, if you look, we have a TCP connection on my current address, 192.168.1.7. And I'm opening up a port for this connection. It's 49,438. And then, our foreign address, what are we connecting to? We're connecting to 52.159.127.243 at port 443. Port 443, we said, is Hypertext Transfer Protocol Secure. So, this is web traffic. And if you notice, the state, it says a connection is established. So, I've established connection between these two ports and we can send information back and forth. And that's essentially what we are gonna be trying to do throughout the scope of these videos coming up. If you know, in the state, we've got different states. We've got a listening state, maybe like we're just listening for an incoming connection, but there is no connection. We have an established connection. We have a closed connection, all for TCP. And then, if you notice down here under UDP, look here, none of that information is present, almost as if UDP doesn't really care to be listening for connections or making connections. And so, just kind of a little cool command you hear, you can look at some of the things that you have going on with Netstat. So, let's wrap this up and just quickly talk a little bit more about some of these connections. So, when we make a connection at a specific port, the service that's running on that port typically has to choose some sort of protocol for communication. And the two primary ones are known as transmission control protocol or user data-gram protocol, TCP and UDP. And a big distinction here is that TCP is a connection-based protocol. A connection has to be made before any data can be sent. And we sort of saw that when we looked at my Netstat output, we saw that there was a listening state or an established state. Once the connection is established, then data can be sent. And so, TCP is typically used to create a reliable error-free connection. It's going to ensure that all data that was sent is actually received and it keeps track and organizes all of the data packets that are sent. UDP, on the other hand, is what's known as a connectionless protocol. So, no connection has to be made before sending data, right? On my Netstat output, we didn't see anything about our connection status. UDP tends to be faster because no connection is required, but you may not receive the data in the order that you sent it, and you could actually have missing data. So, UDP, TCP is very secure, right? Or not secure, I shouldn't say secure, but it's more reliable. We establish a connection, we make sure that there's a connection. We send packets of information. We wait for confirmation that the packets were received, and we continue on. UDP is less reliable. UDP really doesn't care. UDP is just like, hey, I'm going to start sending information out, and hopefully it gets to where it needs to go. Now, what exactly is a socket? Because our whole goal here is to write programs, Python, networking applications using sockets. And so, we can define a socket as one endpoint of a two-way communication channel between two programs that are running on a network. So when we create sockets, we have to specify the internet protocol and the communication protocol that the socket will use. So there has to be some agreement of how the information is going to be sent. And so, imagine if we create an IPv4 TCP socket. So what we'll do is we'll have one socket, our server, essentially listening for incoming connections at a specific location. The location being their IP address and a specific port address. Then another socket, the client, will connect to that specific IP port address to open up a line of communication. So a connection will be made using the IPv4 TCP socket. In contrast, if we create an IPv4 UDP socket, what we'll do is, we'll just create the sockets on both ends. And we'll just start simply sending information back and forth to a given location without any connection. So if we know the IP address and the port address our server is running on, we're not going to connect to it. We're just going to start sending information to it in hopes that it gets there. So in the next couple of videos, what we'll do is we'll start looking at the socket module for Python and how we go about creating IPv4 TCP sockets and IPv4 UDP sockets and some of their similarities and some of their differences. So hopefully this was a good introduction to some of these concepts of lands and wands and IP addresses and port addresses and TCP and UDP. There's really so much more that we could talk about in regards to this, but I just wanted to give a quick refresher here. So everybody's at the same baseline as we move forward into our next videos. So I will see you then. Hello and welcome back. Now that we know some of the fundamentals of networking and sockets, we are going to begin working on creating a server-side script for some communication using the sockets module. So I'm going to start here by opening up a new file. So file, new file, we'll click a Python file and I'll just put a comment up here. I'll say TCP server side and I'm going to save this. So I'm going to go to file, save as, of course you can hit control, ask to save. And I'm going to save it in my dedicated directory which was on my desktop. And inside my folder, Python socket examples, I'm going to create another directory. So new folder and we'll just call this one. We'll call it socket intro and the reason why we're going to have some directories here is we're going to have a lot of different projects where we have a server.py script and then a client.py script. And we want them to only correspond to each other. So we're going to save this one inside of this sub directory and I'll just call it simply, I'll call it TCP underscore server. Okay, so perfect. So now that that's saved here, the next thing I'm going to do is I think it might just help you all depending on the device that you're watching. I'm going to go to file preferences and settings and I'm going to up the font size here. I have it set to 14 right now. Why don't I bring it up to 20? It might just make things seem a little bit bigger and I wanted to show you that in case you were interested in increasing your font size as well. Okay, so the first thing that we're going to have to do is we're going to have to import the socket module which comes pre-defined or pre-installed here in Python. So I'm going to just use an import statement and I'll import socket. So now with the socket module loaded, we can create a brand new socket. And since this is going to be the server side, I'm going to name my socket server socket as it's going to serve as the server in my communication channel. Essentially, the thing that is always going to be listening for incoming connections. Now, so let me name that, same name at server socket. Now, when we name or when we create our server side socket, we have to be specific with what internet protocol and what communication protocol we're going to be using. So we said for our purposes, we're going to be using IPv4 and mostly TCP. We'll do a little bit of UDP coming up here in the future. So to do that, there's a specific way that we can name those things here in Python. So IPv4 is going to be referenced as address family INET or essentially AFINET and then TCP is going to be referenced as SOC stream. So I'm going to put a comment here. I just think it's going to help us in the future. I'm going to say create a server side socket using IPv4 and that is going to be AF underscore INET and TCP and that is going to be SOC underscore stream. All right, so let's see how we do this. We've named our socket server socket. To create this socket, I'm going to call the socket module and then I'm going to call the socket method. And so that's going to create our socket. So here I'm calling the module that we just imported and here I'm calling the socket method. Now inside of here, I have to pass that information. What internet protocol we're going to use? We're going to use IPv4. So I'm going to call socket.AFINET. So there's our IPv4 internet protocol and now I have to pass in TCP protocol. So I'll do socket.SOC underscore stream. All right, perfect. And so that is going to create our socket for us. So now that our server socket is created, we have to do something very important here. Since this is our server side, essentially the thing that is always going to be listening for incoming connections, we have to bind or essentially attach our socket to a given location, a specific location where the socket should be listening for incoming connections. Now this location has to be given as a tuple with two pieces of information, the IP address and the port address of that desired location. So we want our IP address to essentially be the IP address of our current machine. And so we could just look it up. So like if I open up a PowerShell here and I think in Windows it's IPconfig, yeah IPconfig, perfect. So if you look down here, here's my IPv4 address, 192.168.1.7. And I could just hard code that in as the IP address. But the problem is, is if I go to a new, let's say a new Wi-Fi network or maybe my router is going to assign new IPs if I shut my computer down, that can change. And so we don't really want to hard code that in, but instead we want to get the IP address dynamically using the Sockets module. So let's see how we might actually do that. So I'll put a comment here and we'll say see how to get IP address dynamically rather than hard coding it. And so we're going to do this a couple of different ways. So we're going to print some information to the screen here. First, I can get the hostname of my machine by calling socket.gethostname. All right, and I'll put a little comment here that this is going to be my hostname. And so if I run this now, what we should see is the name of my machine. And the name of my machine is SpecterTacArmo. So Specter is the brand of HP laptop I have. I have an HP Specter laptop. And then Armo is my last name. So now that I have this hostname, using that hostname, I can get the IP address of that specific hostname. So to do that, and we'll print this to the screen just to verify it, I'm going to use socket.gethostbyname. So we're going to get the host that has a specific name. What name? Well, we're going to get the name by calling socket.gethostname. So we're kind of having these two methods nested inside of each other. And so this is going to give us SpecterTacArmo, and then we're going to get the IP address of the computer that has the hostname Specter.Armo, or SpecterTacArmo. So I'll say IP of the given hostname. And so let's see if we run this now, do we get our IP address? And we get it right here, 192.168.1.7. So if my IP address were to change, I don't have to come back in here and then adjust the code accordingly. Perfect. So now that we have our IP address, we just have to pick a port address to run the server on. And so I'll choose a high numbered port to ensure that there isn't something already running on the chosen port. Most lowered ports are reserved for well-known services or programs. So I'll use just an arbitrary port. I'll do 12345. All right, so let's set this up. So we're going to put a comment here. We'll say bind our new socket to a tuple. And that tuple is going to be IP address and port address. All right, so we'll call our socket, server socket. And then we will call the dot bind method. And so this is what's going to essentially attach it to a specific location, where it's always going to be listening for incoming connections. Inside of here, I need to pass this as a tuple. So I'll need another set of parentheses. The first thing that I'll do is I'll give the IP address. And we're going to get that IP address just like we talked about before, socket.gethostbyname. And then by what name? Well, we're going to call socket.gethostname to get the name of the computer. And then we'll get the IP address of that name. And so now I'm just going to come outside of the parentheses right here. And I'll put a comma, because now I need to specify my selected port address. And we said for this, we're just going to arbitrarily choose 12345. Awesome. So our server side socket is now created. And it's bound to a specific location. The last thing that we have to do is we have to tell it that it should listen for incoming connections. So like we created the socket, we sent the socket to a specific location. The last thing that we have to do is say, hey, you should be listening for incoming connections. So we'll just put a little comment here. We'll say, put the socket into listening mode to listen for any possible connections. And so to do that, we just simply call our server socket, the socket we named, and we'll call the dot listen method on that server socket. Perfect. So if I run this right now, hopefully we won't get any errors. Nope. So no errors here. So that tells me that this socket is essentially listening. But you can see the program just stopped. So we're going to need to add more to this to make sure that our server socket is continuously listening. But I think this is a good place to stop for right now. I'm going to keep this open, this file open, because we're going to add more to it. In our next video, we're going to begin working on our client-side script. So I will see you then. Hello, and welcome back. Now that our server is up and running, let's create a new file that will hold our client script. So I'm going to come over here, File, New File. We'll name it a Python file. And I'll hit Control-S to save. I'm in that same location, the directory socket intro that I was before. And I will call this TCP Client. All right, and I'll just put a little comment here. It will just say TCP Client-side. The first thing that I have to do is import the socket module, so import socket, just like I did before. And so now what we'll do is we're going to create another socket, similar to what we did on our server side. So we're going to call this socket. We'll call it ClientSocket. And we will then use the socket module to create the socket, so socket.socket. And we have to pass in the correct information here again. I'll put a little comment here. I like the comment thing. So I'm going to just say create a Client-side IPv4 socket. And that's going to be using af underscore inet and TCP, which is socket underscore stream. So let's pass in that information. So our client-side socket is going to be using ipv4, so socket.af underscore inet, comma, and TCP, so socket.sock stream. All right, perfect. So with our server, if we come back over here and look at our server socket, we had to essentially bind it or attach it to a given location and then tell it to listen at that given location. With our client, we don't really have to bind it or attach it to anything to a specific location. And we definitely don't want to just sit there and listen for incoming connections. Instead, what we want to do is we want to have our client socket go connect to some other already established socket, like a server socket, at a specified location. So here, what we'll use is the connect method. And so for our purposes, we have to tell the socket where it's going to connect. So we're going to need an IP address and a port address. And I'm running both the client and the server scripts on the same machine here. So I'm just going to use my local IP address again, which we know we can dynamically get using the socket module. So we'll say here, we'll say connect the socket to a server located at a given IP and port. All right, so we'll take our client socket and I'm going to call the dot connect method. And inside of here, I'm going to pass that information as a tuple. And so the first piece of information we're going to pass is our IP address. So we're going to do socket dot get host by name. And then we'll do socket dot get host name. And that's going to get us our IP address very similar to what we did over here on our server side. And then we'll just pass in our port. And so we're going to keep the same port number as well. So we'll do port 1, 2, 3, 4, 5. Awesome. So that's great. So this IP and port are where the server is waiting, listening. And it's the same IP and port that we're going to tell the client to go connect to. So this seems like it should work. But now, once the connection is made between the sockets, what exactly do we want to do? Well, we want to send some data. That's exactly what we want to do. We essentially want to be able to send data back and forth between these two sockets. So right now, our server is set to listen for an incoming connection. So I'm going to go back to my server side script. So what is it supposed to do once it receives an incoming connection? Well, the first thing that we're going to do is we're going to try to get the information about that incoming connection. And so we're going to start, if you notice, if I run my server script, it runs and then it stops. So we don't want that to happen. We want it to listen continuously or infinitely while connections are trying to be made. And so we're going to do that. I'll do that with an infinite while loop. So I'll say here, I'll put a little comment. We'll just say listen forever to accept. And right now, we'll accept any incoming connection. Any connection. So we'll say, wow, true. And now let's take a look at what's going to happen here. So when a connection is made through our client socket, we want the server to accept or allow that connection. And so we can do that with the accept method. Now, this method returns two pieces of information. It returns a socket object or the socket that was used to make the connection, our client socket. And it returns the address of the incoming connection. So let's grab those two pieces of information and then we'll use some print statements to maybe print that out so we can see what's happening here. So we'll just say inside of here, we'll say accept every single connection and store two pieces of information. All right, so we're going to get the client socket. So we're going to get a socket object, hopefully, and then we'll get the client address from here. And so we want to accept our incoming connection. So I'll call my socket server socket and we'll call the dot accept method. So when our client socket tries to connect to our server socket, we will accept it and we're going to get two pieces of information. We're going to get information about the socket that was just connected and then about that address. So let's use some print statements here to print some information. So I'll say print and we'll call the type function. I want to see what type of object the client socket variable is that we just grabbed here from the accept method and then we'll actually print that information. So we'll say print client socket and then we'll do the similar thing to the client address. So we'll call the type function and pass in client address. And this might just help us in the future as we're trying to write more complicated programs. It's good to know what we are getting from this accept method. And so then we'll print client address. Okay, awesome. Let's also maybe print a message to our server. So on the server side's terminal, letting us know that someone has connected to our socket. So we'll say print and I'll use an F-string here and we'll just say connected to and then we'll pass in the client address that we connected with. So we'll pass in client address and then I'll just put maybe an exclamation point and then a new line character so it breaks it up. So now if we think about this, what we're gonna do, well, let's run this. Let's see how this works. So here is my server, it's running. Okay, so now we are in our infinite while loop. You can see that the program hasn't ended. And so now if I run my client script, hopefully we will actually connect here. And so we'll start another instance. No errors on this side, program is still running. If we go back, we can see, perfect. So if we look here, we can see that we printed out the type of the client socket. So it is a socket object and there is that socket object right there. So this is the client socket that we connected to. You can see that AF.inat, Soxstream, all that stuff. Here is the IP address that we are connecting to and the port address, awesome. And then we're printing out the address that we got, which is a tuple, which is what we expect. And that's 192.168.1.7, our local address. And then if you notice, that port number 50277 is not the port number that we had specified in our client script, right? We specified 12345. Well, 12345 is the port address we want to connect to and this is the port address that the client is using for that connection, all right? So the client isn't gonna connect at that port. This socket is running at this arbitrary port number 50277. But we look, we get our nice connected to and we get our information. So everything here is working out really nicely so far. Perfect, so I'm going to just, I'll stop the process here, all right? And close these out. And the last thing that we'll do here in this video, so now that we have made the connection, let's have the server once it gets a connection actually send some information over to the client. So we have the information about the client socket that we just connected to, right? So it's stored right here, client socket. So we'll take that socket that we just grabbed and we'll call the dot send method on it. And so let's send a string. We'll say you are connected. So let's put a new comment here. We'll say send a message to the client that just connected, connected. And so we'll call the client socket, which is the socket that we grabbed when we accepted the connection and we'll call dot send. So we want to send information back to that client socket. And so I don't know, I'll pass in the string you are connected. And so perfect. So let's try running this now and let's see what happens. So if I click run, all right? I'll click run over here on my client to get the connection. And if we look, we get an error. And so our error here is on the line where we're trying to send our information. It says a bytes-like object is required, not a string. And so this is really important here. So we can't just send strings through our socket, our line of communication. What we have to do is we have to encode it and send it as a bytes object. So strings and other pieces of data have to be encoded with a specific encoding method in order to enter the data stream between our two socket channels here, which really isn't a problem because there's a method, a string method, we can use to do that. We can call dot encode on our string. So if we come over here, I'll type in, so here's our string you are connected and then I'll type dot encode. And typically what we'll do is we'll pass in an encoder. I think the encoder we'll use is UTF8, so UTFTEC8. I think that is the default encoder. So you could leave that out, but I like to specify it because maybe we'll change that in the future. So now if we run this, hopefully we won't get that error, we'll be able to send that information just fine. So we'll run, we'll run. And if I come back here, we can see that there was no error so that data is being sent without any issues. Of course now that data is being sent over to the client but we gotta do something with that client script in order to actually display the information. However, I think this is a great place to stop here in this video. In our next video what we'll do is we'll wrap up sending data between these two sockets and finish it up here with the TCP communication. So I will see you in that next video. Hello and welcome back. Now that we are sending data on our server side, we're sending this encoded message you are connected and we're gonna encode it as a bytes object. Let's go and receive it on the client side. So I'm gonna come over to my client script and we'll say, I'll put a new comment here. After the connection is made, we'll say, receive a message from the server and we'll also just claim here when we do that, so we can use the receive method. And when we use the receive RECV method, what we have to do is pass in the maximum number of bytes that the socket should expect to receive in one single message. So I'll add that here. I'll say, you must specify the max number of bytes to receive. So we're gonna create a variable. I'll call this variable message and we'll take our socket, client socket and we'll call the dot receive here method. And inside of here, we have to pass in the maximum number of bytes that we're gonna receive. And so right now, I am just going to pick a very, you know, a large number here for just simple text communication. I'll do 1024. All right, and that's not gonna be an issue at all here. But you may be asking yourself, well, what happens if we try to send something larger than 1024? And I'm just gonna say for now, it won't be a problem. But later on, when, say, we are creating like a multiplayer game and we're sending lots of information, it will become a problem. So at that point, we will address the issue by using fixed length headers that specify the size of whatever incoming packet is coming in. But for right now, we're just gonna, we'll arbitrarily set this size to be 1024. And maybe we'll play with it a little while in a couple of videos and we'll see the shortcomings of doing this. So let's test everything out. And let's see if this works. Well, we should probably print the message, right? So we'll say print message. Otherwise, we won't know, we got it. So I'll run the server. All right, perfect. I'll run the client. And hopefully we will send that information and then we'll print it. And you can see it did sort of print it. And it says you are connected and it's got this weird like be in front of it. And that's because if we actually print, let's print the type, we'll call the type function on message. What we'll see is it's not actually a string. I don't think it's a string. Oh, I got a, yeah, that's right. So I just got an error. It says only one usage of each socket address is normally permitted. I was trying to run the server again without stopping the previous one that I had run. So you can only run this once, right? So now that's running. And if I run it again, let's take a look. So here's our message. You are connected, but it's not a string object. It's actually a bytes object. So recall that if we go over to our server here, we had to encode the string and turn it into a bytes object to send it over our data stream. And so now once we got it on the client side, what we should typically do is we should decode it on the client end. And so we can do that by using the decode method for strings. So message, here is the message. And I will just say message.decode. And then I'm going to pass in the same encoder that we used on the client side. So I'll pass in utf8. Again, I think this is the default one, but I still like to print it in there. So I'll delete this. And if we run this now, hopefully we should see that we're getting a string object. Oh, and I made the same mistake I did before. Let me stop the previous instance and run my server. All right, so there's that. We'll run this here. And so you can see we now have a string object. You are connected. Awesome, so this is working out great. I think it's good practice to maybe just talk about closing our socket connections once our communication is done. So the last thing that I'll do here is I will close the client socket. And so this is on my client script. And I'll just say clientsocket.close. And maybe I'll go back over and do something similar here. I don't think I need to print the type. Oh, I got rid of that there, so that's good. So I'll save this and I'll come back over here and let's close the server socket as well. So I'll maybe just come down here and say close the connection. And so we'll say server socket.close. All right, and if I run this, what's interestingly, I think we're gonna get an error. And let's just quickly discuss why we're getting an error. Oh, I keep doing that. I gotta stop this. There we go. I'll run this. All right, I'll run this. Sends the information you are connected. That is closed, great. And if we come over here, let's look at the output. We do get an error. And the reason why we get this error is we are closing the socket, but we are still stuck inside of this infinite while loop. And so the socket, which we just closed, is now trying to accept a new incoming connection. So we can't do that. That's like an issue, right? So one of the things that we can do is once we close the socket here, we'll just use a break statement to break out of the infinite while loop. The last thing that I'm gonna do is just clean this up a little bit. I'll put some comments here. So we're not printing out our hostname and IP address, and I don't really need to print these things out anymore. However, I will leave them in there just for like debugging purposes, okay? So if we run this, everything should be good. There's our server. All right, nothing's happening. We'll run this. There's our client. It says you are connected. And if we look at our server, it says we have been connected to 192.168.1.7 at port 5427. What a weird way to read a number. 50427, 50,427. Awesome, so everything is working really great here. We got a nice basic TCP server and TCP client using our Sockets module. I think this is a great place to stop, and I will see you in the next video. Hello, and welcome back. In our last video, we set up a very simple client-server relationship using a TCP socket. Important things to note here. On the server side, we created a socket and then listened for incoming connections. We created the socket, we bound it to a specific location, and then we listened for our connections. And then on the client side, we actually had to go and connect to that established socket. And then once our connection was established, we simply called the send and receive methods to send data back and forth. Now, we're gonna be using TCP Sockets for all of our projects in these videos, but for completion, I wanted to quickly show a UDP client's server socket relationship. So recall, UDP is a connectionless protocol. So no connection will be made. Data is just simply going to be sent and received. So I'm gonna start by creating two new files. So I'll do file, new file, we'll make it a Python file, and I'll make a second one file, new file, I'll make it a Python file. Oh, I guess I should save it first. So I'll save this first one in our Sockets intro. I'll call this UDP server. All right, and then file, new file, and we'll call this one, we'll save it as UDP client. All right, perfect. So now that I've got those two files here, let's start on our server side. So I'll just put a comment here. I'll say UDP server side and we'll import the socket module, just like we have done in the past. Okay, so now on the server side, I'm gonna create a server socket and it's gonna use IPv4 and then UDP instead of TCP protocol. So I'll put a comment, we'll say create a server side socket that uses AFinet, I'd socket IPv4, yep. All right, and we'll then say and UDP. So instead of Soxtream here, which is how we reference TCP protocol, we'll use sock underscore dgram, all right, for UDP, datagram. So let's create this socket. So we'll say server socket is equal to, I'll call my socket module dot socket. And now inside of here, we have to pass in those two pieces of information. So it's gonna file IPv4 protocol, socket dot AF underscore inet and it is going to be UDP. So socket dot sock dgram. All right, perfect. So now that we have our server socket, what I'm going to do is I will bind it or attach it to a given location, just like we did with our TCP socket. So we'll say bind our new socket to a tuple that is going to be IP address and port address. All right, so we'll call our socket server socket and we'll call the bind method and inside of here, we're gonna pass the tuple. We'll pass in our local IP address and we know how we get that. I'm gonna do socket dot get host by name and that's gonna give us our IP address of a specific host name and we're gonna get the host name by calling socket dot get host name and I'll choose an arbitrary port number. Again, I'll use one, two, three, four or five. Awesome. So now we've created our UDP server socket and we have it bound to a specific location. Now in our TCP server, if you look, the next thing that we did is we put it into listening mode to listen for our possible incoming connections. However, we do not have to listen for any incoming connections here because UDP is a connectionless protocol. Instead, I'm just going to sit around and I guess wait to receive some information from a client that has sent information to this specific IP and port address. So I'm gonna actually put a comment here and I'll say we are not listening or accepting connections since UDP is a connectionless protocol. That's just there for my, I think my understanding and hopefully your understanding. So we're just gonna wait to receive some information. So rather than use the receive method, like we did to get information here on the TCP client, we use the dot send and then our client use the, where was it, dot receive, we have to use the receive from method when working with UDP. So I'm gonna come back over to my UDP server and we'll use the receive from method and this is going to return the data that was sent, like maybe a message, as well as the address information that it came from. So I'm gonna grab both of these pieces of information and grabbing the address here is gonna then allow me to maybe send some information back because remember no connection was made so I need to know where this information is gonna be going. So I'll create two variables here. I'll create message and address and we'll send it, set it equal to our server socket dot instead of receive, we're gonna say receive from. And again, inside of here I have to specify the maximum size of the object that I'm gonna receive and we'll just arbitrarily say 1024 right here. All right, perfect. And so now let's go through and actually print this information. So we'll print the message. Of course, we know that this message, when we get it, is gonna be a bytes object. So I wanna decode it. So I'll say dot decode and I'll pass in UTF eight as my encoder here. And then let's also print, for the purpose of this, let's also print the address. Okay, awesome. I think this looks good. Now let's head over to the client side. So I'm gonna save this control as to save and let's head over to our client side and see what we're gonna do here. So we'll put a comment here. We'll say UDP client side and we'll import socket. And on the client side, we're going to make a UDP socket. So we'll say create a UDP IPv4 socket. And so we'll say client socket is equal to socket dot socket. And inside of here, I wanna pass in the right information. So I'm going to use socket dot AF underscore INAT. There's IPv4. And then we'll do socket dot sock underscore D gram. And so now there is my UDP socket all created. Perfect. So now that we have this, let's simply send some information to our server, right? We've got this client. Let's send some information to our server. Now, if we look over here, when we use TCP, we use the send method. That was all we needed, right? Cause we already had a connection made. We were just sending information through this connection. But UDP is connectionless. So we don't necessarily have a connection, a place to send this information. So what we have to do is we have to specify where we are going to send our information here. So let's say, you will say send some information via a connectionless protocol, protocol. So we're gonna, instead of using the send method, we'll use the send to method, just like we used receive from instead of receive, we have to use send to instead of send. So I'll say client socket dot send to, and then what do I wanna send? I'm gonna send the string, hello, I don't know, hello server world. And we know that we have to encode this string. So dot encode, encode, and we'll pass in our encoder, utf8. And now I need to specify where exactly I'm supposed to send this. So I'm gonna send it to a specific location, an IP address, and so we're gonna use our local address. So socket dot get host by name, socket dot get host name, and then a specified port address. And we're using one, two, three, four, five. So I'm not actually making the connection, I'm just sending that information there to that desired location. Okay, so I think this looks pretty good so far. And so if we run this right now, let me save this, I will run my server. So we're expecting to receive a message. So here's my UDP server, no problem. And if I run this, here's my client, we should hopefully make a connection. And if I come back over to my server, it says hello server world. So the message was received and then we are printing information about that connection. So it looks like our UDP server, client socket is working nicely here. Connectionless, right? It is connectionless, perfect. So I think this is a good place to stop here in this video. In our next video, maybe we're gonna mess around with our buffer size. So we've specified that the maximum size we should expect to receive is 1024. And let's talk about what that means if we change it for both the UDP and the TCP server and client relationships. So I'll see you in that next video. Hello and welcome back. Now that we have completed really basic TCP connections and UDP connections, let's play around a little bit with the buffer size. This maximum size, we kind of arbitrarily sent to 1024 bytes for our message packets. And let's mess around with it for both the UDP and the TCP sockets and see how they handle them. So we'll start with our TCP socket. So with TCP, if I try to send something that is larger than the buffer size, the message is gonna go through. It is guaranteed to get there. However, you might not get the whole message at once, but it's ensured that the message will get to its location. So to show this, let's open up our client side TCP. And right here where we are receiving our message, I'm going to copy this code where we're getting the message and then I'm printing it, copy it, and I will paste it in here. So we're gonna receive it twice here. And then let's also change the buffer size from 1024. Let's just change it down to 10 bytes. Okay, perfect. So let's look at our server. So I'm gonna save this. Let's go over to our server. And if we look at the server side here, we are still sending one message to our client. It says you are connected. So let's now run this. On the client side, we're going to receive it, but we're saying our maximum size can only be 10. So let's see what happens here. So if I run this, all right, and now I run my client, interesting, right? So you can see we're getting our entire message. We received the first 10 bytes, U, R, Co. And if we look, that's one, two, three, four, five, six, seven, eight, nine, 10. And then in our second message, we're getting the rest of it, you know, naked, okay? So we did in fact get it. In our, you know, first receive call right here, we get the first 10 bytes, and then in the second receive call, we get the rest of our message. Even though our server only sent one message, it sort of is stored in guarantees that the information is gonna get there. We just have to pull it from the data stream. So that's how it's gonna work with our TCP. And so I'm gonna actually just quickly go back and change this. I'm gonna get rid of the second message here, and I'm gonna change this back to 1024 and save that so we don't mess up any of those changes. So now let's look at the UDP side. So I'm gonna come over here to where are we receiving? So we're receiving our message right here. So let's receive this, I'm gonna change this to 10. Okay, perfect. And so, you know, we know that this isn't gonna be enough, right? Hello server world is gonna be more than 10 bytes. So maybe I wanna run this a couple of times. So I'm gonna, you know, copy this. I'll copy the whole thing. And we'll paste it down here. So let's run our server and see what happens. All right, so our server is running. Let's run our client. We're sending the information. And if you notice here, nothing happens. The packet is simply dropped. We get an error. It says a message sent on the datagram socket was larger than the internal message buffer or some other network limit. Or the buffer used to receive the datagram was smaller than the datagram itself. So interesting, right? It doesn't work. So to quickly recap, TCP is a connection-based protocol that essentially guarantees that our packets are gonna be delivered. You know, they might not be delivered all at once depending on what the buffer size is, but the information will be in the data stream and we can pull it down, you know, at a later time. UDP, on the other hand, is a connection-less protocol that does not guarantee that packets are delivered. And so, you know, here, in this case, there was an error and so the packets just dropped. You're not gonna get any of that information. Now that has its pros, it has its cons. You know, because of this, UDP typically is a faster, you know, is faster. And that's if you're, you know, working with data that's constantly being updated and being sent. Maybe you don't really care that we dropped a packet because you know an updated one is gonna be coming, you know, right after it. Maybe things like a video call, right? UDP is something that's gonna be desired. However, for what we're gonna be doing moving forward, we're gonna be using our TCP connections. So I'm gonna just change my UDP buffer size here back to 1024 and one of the things that we'll do in the future is we'll talk about how we might handle changing this buffer size so that it's dynamic, so that we can determine how big the packets are that are gonna be coming in and set our buffer size accordingly. But that's something that we're gonna be doing that's a little bit more advanced and we'll be doing it later on in these videos. So for right now, I think this is a great place to stop. We have a nice overview of TCP sockets, UDP sockets and we're gonna start diving further into those TCP connections starting in our next video. So I will see you then. Hello and welcome back. In our last few videos, we saw how to send data over the network using our socket module. Now that we understand how TCP and UDP sockets work, let's expand on our TCP server client socket. In the next few videos, we will build on this idea such that our data can be sent from server to client and client to server repeatedly. Essentially, we're going to build a basic two-way chat that will take place via a terminal. So to begin, we're gonna create two new Python files and so I'll just come here and do file, new file. I'll set it as a Python file. I'll put a comment here. I'll say chat server side. All right, it's gonna be our server side chat and I'm gonna save this still in my socket intro folder and I'll just call it chat server. All right, and then I'll create a new file, file, new file, set it as a Python file and I'll say client chat side. I mean chat, client side, chat, client side. Perfect, all right, and I'll save this and I'll save this as chat client. All right, wonderful. So I'm gonna start with my server here. So the first thing that we're going to do is we will import the socket module. So import socket and now what we'll do is before, you know, we were kind of like typing in our IP address, our ports, our encoders, maybe the maximum byte size. We were just mixing it all within our program and I think it'll be better for us if we pull that information out and define them as some constant variables that we're going to use throughout the scope of our program here. So I'll say define constants to be used. So we'll start with our host IP address. So I'll say host IP and so we're gonna just get the IP address of our local machine. So socket dot get host by name and then we'll pass into here socket dot get host name. All right, so now we have our host IP and if we decide we wanna change this later on, we can just come over here and override that command. Let's do something similar for our host port address. So we'll say host port, oops. There we go, host port and I'm gonna pick that arbitrary value, one, two, three, four, five. You can use whatever value you want, right? Just make sure you're not using a port that a service is currently running on. Next, I'm gonna define an encoder, encoder and we'll define this as UTF-8 and we'll use this to encode and decode any of our information. And then lastly, I'll pick a byte size for our packages, our streams of information that are coming in that's large enough so that we really don't have to worry about chopping off any of the message or anything like that. So I'll just say byte size, I can spell byte size is gonna equal to 1024, okay, perfect. So we've got those things defined. So now let's create our server socket using the socket module. And so again, we're gonna set the socket to use the IPv4 and TCP protocols. So we'll say here, create a server socket and so we'll say server, we'll call the server socket, server socket and we'll call the socket module and we'll call socket the socket method and inside of here, we'll pass socket.af underscore inet. There's IPv4 and then we'll do socket.soc underscore, oops, all capitals, stream and there's TCP. All right, perfect. And let's also, we'll say create a server socket, bind it to a IP port and then we'll say and listen. We're gonna do all three of these things right here. So we'll create the socket since we're, now that the socket is created, we'll bind it to a location. So we'll say server socket, we'll call the dot bind method and in here we're gonna pass a tuple and that tuple will be the host IP and host port constant variables that we had defined earlier. And lastly, since we are using a TCP protocol here, TCP connection, we are going to listen for any incoming connections. So let's do that. So we'll say here, server socket, listen. Okay, perfect. So now what we can do is we can quickly print a message to the terminal informing the user that the server is essentially running. So we'll just, this will kinda just be some visual feedback. And then once we're here, we'll also listen for any incoming connections and if we get an incoming connection, we'll send a message letting the incoming client know that they have successfully been connected. So let's do that. So we'll say print, we'll just say accept any incoming connection and let them know they are connected. So we'll give some sort of response back. So the first thing we'll do is we'll just print that the server is running. So that'll be visually for us on the server end. Oh, let me put that new line character inside of my string, backslash n, all right. Now that we have that, let's accept any incoming connections. So remember when we accept an incoming connection, we're gonna get two pieces of information. We're gonna get the socket that is connecting to us and we're gonna get the address of that socket. So we'll call this our client socket and we'll call it client address. We'll get those two pieces of information by calling our server socket and we'll call the dot accept method on the server socket. So it'll accept anything that connects to it and then store the information in these two variables, client socket and client address. Awesome, so now that the connection has occurred, we're going to send some information to the client socket to verify that they have successfully connected. So let's send some information to the client socket which we have right here. So I'll call client socket and we'll call dot send. Recall, we don't need to send to like we did with UDP because we have a connection form. So we can just send right through our connection channel and we'll say you are connected to the server dot, dot, dot. Sure, and then I'll do backslash and for a new line. Now don't forget here, this is a string and if we wanna send information, we have to encode it and turn it into a bytes object. So I'll call dot encode and inside of here I'll pass my encoder constant variable which is right up here. So so far I think this is pretty good on our server side for our chat. I'm gonna save this and I'm gonna come over to our client file. So right at the top here I'm going to import socket just like before, we gotta make sure we bring in the socket module and now let's also set some constant variables. So we'll say define constants to be used. This is just gonna help us. I think it's a nice thing for us to do moving forward. So I'll have a destination IP address and so for me my destination IP is actually gonna be the same as my host IP, right? We're on the same computer. So I'm just gonna do socket dot get host by name and socket dot get host name. Okay, and I think later on in a future video further along I'll show you how to configure your router so that you can have connections coming in from different places and that sort of thing, but we're not there yet. So we're just gonna do everything local on the same computer. Let's set up a destination port, so dest port and we'll choose 12345. We'll do an encoder again and our encoder is gonna be UTF-8. We'll make sure that those are the same and then we'll specify a maximum byte size of 1024. And again, we're not really worried too much about sending a message that's bigger than that at this point. All right, perfect. So now once we have these things defined let's create our client socket again and we will connect to our server. So we're gonna kind of reproduce this section of code but remember on the client side we don't have to bind and listen we're just gonna make a connection. So we'll say create a client socket and connect to the server. So in here I'll call this client socket and we're gonna do socket dot socket. All right, so call the socket module and the socket method in here. We want to have it be IPv4 so socket dot AF underscore inet and we wanna follow TCP protocol. So we'll do socket dot sock underscore stream. All right, so that creates the socket and so now we have to connect to our server. So we'll call our client socket which we just created and we'll call the dot connect method. And in here we have to pass a tuple of where it needs to connect to. Well, it's gonna connect to the destination IP that we specified and the destination port that we specified. So we can change these whenever we want to and we'll alter where that connection is going. All right, awesome. So if we look here, I think this is maybe a good place to stop. If we run this, if I run, let me run my server first. All right, so server is running, that looks great. And if I run this, we just stop, right? We just stop. So the server has sent a message. I think the server has sent, you are connected to the server, we're sending it, but we haven't yet received it here on our client side. But we'll work on that I think in the next video. This is a great place to stop. So what we now wanna do is have the ability for both the client and server to send and receive information, essentially until one party decides to quit. And when we write that, that's where we'll get receiving that message here on the client side. So this is a great place to stop and I will see you in our next video. Hello and welcome back. Our server and client scripts here for our basic kind of one-way chat are well on their way. So now let's actually work on adding that chat functionality. Let's start with the client side since we are already sending a confirmation message on the server side to that client. So what we need to do is we need to essentially receive this message, decode it, and then display it. In fact, we're gonna receive and decode and display all of the incoming messages, right? We want lots of these messages to happen. So what we can do is we can put this inside of a loop. So we'll use a while loop. And so we'll say while true. And I don't know, I'll just put a comment here. I'll say send and receive messages. All right, so while true, inside of here, the first thing that we'll do is receive the sent message and we will decode it. So we'll say receive information from the server. So we'll just call this message, all right? We're receiving a message. And so we're going to get that by calling the receive method on our socket that we have here, client socket. So client socket.recv. And inside of here, we have to specify the maximum size, the packet that's gonna come through. And so we've declared that as byte size. And then we know that we also wanna decode this message. So this is going to be a bytes object. And so I'm gonna actually call dot decode right here and pass in our specified encoder. And so I can receive and decode kind of all in one step here. And I think that's gonna be really nice. So the next thing that we're gonna do is we wanna have the ability for a user to essentially end the program, right? And so we're going to check to see if the message that was sent was the string quit. And if it was, we are simply just gonna end the chat. And we'll sort of use this string as a kind of like a flag to indicate that the chat is done. However, when one party receives a quit flag, they should also send a quit flag back to the other party to sort of validate that they are quitting and to start the quit process on the end of the communication channel. So let's see, so let's see how we might do this. We'll say quit if the connected server wants to quit. Else keep sending messages. So we'll come down here, we're gonna check the value of message. So if message is equal to the string quit, then what are we gonna do? Well, we said that we should probably send a quit flag back to the server to verify that we're gonna start the quitting process. So we'll say client socket dot send. So we're gonna send and what are we gonna send? Well, we're gonna send the quit flag right back. And we're gonna encode this using our encoder so that we can send it through our socket here. And then let's just print a message here for our own purposes. I'll do on a new line. So backslash and I'll say ending the chat dot dot dot. Goodbye. Awesome. And then I will call a break statement to break out of the while loop. Perfect. Now, if the message isn't quit, then what should we do? Well, we'll have an else block here for our if statement. Well, we should display the message, right? So let's do that. We'll say print and I'll use an F string here to have a new line. And then I'm going to print the value of the message that we received. All right, perfect. So that looks like it's gonna work out quite nicely here. And so now what do we wanna do? Well, inside of this while loop, once we get the message, we then want to get the client to put in some information that we can send back to the server. So let's do that. So we'll come over here and we'll create our override, our variable message. And we'll call the input function and we'll put a prompt here where it'll just say message. And so whatever the user types in will then be put into our variable message. And then let's send that value back to the server. So to send it, we'll call client socket, oh, silent client socket dot send. And then we'll send message, but we know we have to encode this. So we'll call the encode method and we'll pass in our given encoder. All right, I think that's pretty good. The last thing that I'm gonna do here on the client side is if we break out of this infinite while loop, I am going to just simply, we'll close the client socket. So if we've quit, then we'll break out of here and I will say close the client socket and we'll just call client socket dot close. All right, and I'm gonna save this because I think our client socket, our chat client is pretty much done. So let's head over to the server side and let's take a look at what we have to do here. So we want another infinite while loop. So we'll put a comment here. We'll say send slash receive messages. Okay, and we'll start with a while loop. So while true, we're gonna do something really similar here. So we're gonna check to receive a message from the client socket, making sure that we state the maximum bite size in our encoding method. So we gotta get some information. So we'll say receive information from the client. So we'll call this message and we'll call the client socket, which we have gotten here when we accepted that connection. We have that client socket, perfect. So client socket dot recv of receive and we'll specify our bite size that we have defined bite size. And then we'll decode it, decode dot decode and pass in the encoder that we have defined. Now that we have that message, we're gonna do something almost identical to what we had before. So we're gonna say quit if the client socket wants to quit else display the message, we'll just say. So if the value of message is equal to that string quit, what are we gonna do? Well, we will acknowledge the fact that we received a quit flag and we'll send one back. So I'll say client socket dot send quit dot encode using our encoder. So we'll encode that string as a bytes object and then we'll print our message here. Oops. On a new line, we'll say ending the chat dot dot dot. Goodbye. All right, and then I will break out of my wall loop. Now, otherwise else, so if the message is quit, we'll end the chat else, what are we gonna do? We're gonna print the message. So we'll follow the same formatting. I'll use an F string here. I'll put a new line and then we'll print the value of whatever that message was. And then we'll override that variable message by getting some input from the server here. Input and we'll just say message. And then once we have that new message to send, we are going to send it to our client socket. So client socket dot send and we'll send message. But of course we have to encode that string using our encoder. All right, the last thing that we'll do just like before, once we break out of the wall loop, we'll simply close the socket by calling server socket dot close. So we'll close our server socket that we had originally created over here. All right, so I think this is all set. Let's test this and see how this works. Hopefully we should be able to kind of have like a two way chat going on here. So server is running. We can say client is running. And so if we look here, our client says you're connected to the server and I'll say hi server, this is client. And I'll hit enter. And if we come back over here, we got hi server, this is client. We can say how are you client and send it. And it looks like that message is coming through. How are you client? I am good, you will send it. And then let's see what happens if we type quit, quit. We'll just say quit. All right, and it says ending the chat goodbye. And then over here we've got ending the chat goodbye. So it looks like this is working perfect. So you might not like having to go back and forth and back and forth here. So one of the things that we can do is if I just minimize this and I go to the directory where I've got these files. All right, here they are, here they are. So I'm gonna just come in here, I'm gonna right click and I'm gonna open in terminal. All right, so here we are. I can type in Python and we'll type, what did I call this? Chat server. Yep, so I'll type in Python chat server.py. And there it is, server is running. And so now I'll do something similar. I'll open in terminal. And here I can type in Python chat client.py. And so now I can run them in separate windows and we can kind of see that the same thing is happening. So we can say, hey, what's going on? All right, and then there it is. Nothing, what's going on? Going on with you. And so we're getting that back and forth. So just another way that we can run this and we'll pass the quit flag again, ending the chat goodbye, ending the chat goodbye. Awesome, so this has worked out really nicely. And we now have a nice little program here. Maybe we can put one of these, the server script on one computer on your home network, the client script on another computer on your home network and you just have to adjust, let's just see, you just would have to adjust on the chat client right here, your destination IP. So if your server, I think I'm running on 192.168.1.7 is my IP address. So your server is gonna get their own IP, but then your chat client, you just have to change it. So maybe if you were running this on 192.168.1.15, you could just type that IP address in right here. All right, I think this is a great place to stop. This kind of gives us a really nice overview of some of the functionality of the socket module. I think one of the next things that we'll probably do is try to build on this idea of a chat room. Right now we can only have one client essentially connect to our server. If we try to have more than one client connect to our server, I think we're gonna have some issues. So for instance, I'll run my chat server and my server is running and then I come over here and I run my client, okay, so this is great. We'll just say this is great, all right. And so that went through, yes it is. But let's see what happens if I try to run another client. So I'll come over here, I'll open in terminal and I'll run Python chat client. You can see that it just hangs here because once we have our connection, we're not allowing other connections to happen, right. If we come back over and look at our code here for the chat server, our connection, where are we accepting our connection? We're accepting the connection here outside of this wild loop. And so the next thing that we'll look at is how do we handle having multiple connections on our server so that maybe we can have not just one person connect, but two, three, four, five people all connect and we can facilitate a chat between multiple people. So that's where we're headed. We're gonna need to use another module or another library to help us accomplish that. But I can't wait to begin looking at that with you in our next video. I'll see you then. Hello and welcome back. In our last video, we finished and tested our basic two way chat application between a server and a single client. And this works pretty good as we could send data back and forth from a server to a single client. However, there were some pretty glaring shortcomings and so I wanna talk about a few of them just initially here at this video and we're gonna use those for motivation for our next project. So I'm gonna minimize these. I'll open these up in my terminal here so we can see the chats better. So I'll run Python, Python, chatserver.py. All right, so there's our server. It's running and then I'll run the associated client script for that. So new terminal over here and I will run Python, chat, client.py. All right, perfect. So if we look here, we have a message prompt as soon as we log in. So I can say hi server and then that message prompt gets sent over here and I can say hi client, how are you? And we can have this communication back and forth. However, it's kind of weird that we can only sort of send one message at a time or at least it seems that way. So I can say this is my message and as soon as the client sends it, the message prompt is gone. But what if the client continues to type? So I can say like I am still typing dot dot dot and then I leave it here. Well, when the server responds to this message, this is my message. The message prompt goes back to the client and then that text appears there, which is kind of weird behavior. So I'll hit enter here and we'll send that message. Now what if the client lost the message prompt? What if we type and we hit enter? So I'm gonna say I am typing and hit enter. All right, I just hit enter. And so now if you look, some weird behaviors happening. So now I'm over here and I don't know where the message prompt is going. So it looks like we sort of crashed the program, which is not that good. And we also saw, yeah, see, we got a bunch of errors that we crashed that program. So we definitely don't want that behavior to occur. We also saw, I think at the end of the last video we talked about this that weirdly, we only have two people communicating here, a server and a single client. But what if we wanted three or four or five people communicating? Essentially, what if we wanted more clients? Well, what we're now talking about is more of a chat room rather than a simple chat where multiple people are all together and they can all send messages fluidly or maybe I'll say concurrently at the same time. And this is totally doable and it's something that we are actually going to build. So in order to fix these two issues, we have to introduce a new module called the threading module. See, our problem comes from the fact that in our previous code, like let's say our chat client code. So I'm in here right now. You know, when we send a message, so if you look, we received a message. It was kind of like the, I think we received what the, you are connected to the server. We received that message and then we sent a message. So we send a message, we get the message from our user and then we send the message. Perfect. And so once we send that message, we come back up to the top of our Walupe here and we are telling our socket here that we expect to receive another message. And essentially, like this program sort of hangs until that message essentially comes in, right? The receive method, this method says, hey, wait until we get some data coming through the data stream that we can process as a message. So the tasks of sending, you know, sending here and then receiving and then sending and receiving, they're sort of sequential in our code. And what we want instead is to have both tasks sort of running concurrently or at the same time, such that at any time our client script is looking to send a message if the user wants to send a message and receive a message if one comes in. So we want these two processes to run at the same time. And really the threading module can help us accomplish this. On the server side, we're gonna have, you know, a similar sort of situation here. If you look, we accepted an incoming connection and we accepted the incoming connection outside of the Walupe. Well, we want to accept multiple connections. We wanna connect to all of them and then receive and send information, you know, to all of the connected clients. However, if you know, when I run just my server and I'll run it inside of here, the server is running, the server hangs right here, it's waiting for a connection to come in. And only once that connection comes in that the rest of the program will kind of run. So I can't really put this line of code inside of my Walupe, because it'll hang my program. So we're gonna have some, you know, some big issues here. However, the threading module is going to allow us to run these different portions of our code concurrently or at the same time, right? The sending and receiving of information and the accepting of new clients, we can all run in their own, we'll call them separate threads. So I think that's like a really nice overview and good motivation for what we are going to be doing here. So I'm actually gonna close out of these two scripts here and I'm gonna make a new file. So file, new file, it's gonna be a Python file and I'm going to control S and we'll save it. And I'm gonna back up one level and I'm gonna create a new directory. So we'll call it new directory two and we'll call this terminal chat. Terminal chat room we'll call it. So we're gonna make a chat room that exists inside of the terminal. And so this first program that we're gonna write is just all about the threading module. So I'm gonna call this thread intro.py, sure. And so we'll just import. The first thing that we have to do is import the threading module. It's just gonna help us run programs kind of concurrently or at the same time. And so I'm gonna actually just put some comments here right up at the top to help us understand what is happening. So I'm gonna say threading allows us to speed up programs by executing multiple tasks at the same time. And then we'll say each task will run on its own thread. And then we'll say each thread can run simultaneously and share data with each other. And so that's gonna be, you know, I think really helpful for us for what we want to do if we're gonna try to make a chat room. And so let's just add a little bit more here. We're gonna say every thread when you start, when you start it, must do something. So when you start a thread, it has to have something that it is going to do. And so we can say that, you know, which we can define with a function. So we'll define some functions and then when we start a thread, we'll tell the thread, hey, when you start, you're going to run this target function. So our threads will then target these functions that we are going to write. And then lastly, we'll just say, when we start the threads, the target functions will be run. All right, so let's put this maybe into practice here. So how are we gonna do this? So let's take a look. Let's begin by defining some basic functions. So I'm gonna just define some really basic and kind of arbitrary functions. We'll call them function one, function two, and function three. And each function is just gonna do a simple thing. It's gonna use a for loop to print out the numbers one, two, or three, 10 times. So I'll say def function one. And I'll say in here for x in range of 10, I guess I'll say for i, let's do i, why not? For i in range, it doesn't matter, but I just like i as my iterable a little bit better. We'll say print the word one. Okay, and then we'll say def function two, and we'll say for i in range of 10, we'll say print the word two. And I'm putting a space here just for formatting. It'll help us out later. And then I'll say def function three, and we'll say for i in range of 10, print three. All right, so some really simple functions here that are gonna help us as we test how we can use the threading module. So now as expected, if we call these functions normally, we're, so let's just call, we'll call like function one, we'll call function two, and then we'll call function three. So I'm gonna put a comment here. If we call these functions, we see the first function call must complete before the next. Essentially we'll say that they are executed linearly, right, they're executed in order. So let's just test this out. So we'll call function one, then we'll call function two, and then we'll call function three. And so what we should see is just function one's gonna be called, it's in the, the main code is gonna hang until that's done, and then function two will be called, the main code will hang until it's done, and then function three will be called. So let's run this, and hopefully we'll see, you know, one getting printed out, yep, and that's exactly what looks like it's happening, right? So one gets printed out 10 times. When that function is done, the next one starts, two, and then three. Perfect, so, and maybe you know what, I'm gonna add, I'll add a little bit here. I'll say, nah, this is perfect. I think we're seeing this nicely. So really, we've got a nice foundation here set up for kind of exploring what the threading module is going to do to maybe help us run these three functions not linearly like we're doing here, but rather concurrently. And I think that this is a good place to stop in this video, and we'll explore that concept in our next video. So I will see you then. Hello, and welcome back. In our last video, we kind of laid the foundation for using this threading module. We wrote three kind of pretty basic functions, function one, function two, and function three, where they just print out the words one, two, or three, and we see that when we call them down here, they are executed linearly, right? Sequentially, and so that function one is called, it must complete, and then function two is called, it must be complete, and then function three is called, and it must complete until the program continues. So let's see if we can actually create some threads now to have these functions run concurrently. So what we first need to do is declare the threads using the threading module that we have imported, and then we'll pass in a target. And those targets are gonna be the functions that we wrote right here. And it's these functions that will be run when the thread starts. So I'm gonna put a little comment down here just for our purposes. We'll say we can execute these functions concurrently using threads. We must have a target for a thread. We'll just, for a thread, perfect. So we'll put that in there. So we'll call our first thread T1, and so I'll call, I'm gonna create this thread by calling the threading module, and I'll say dot thread. All right, so there's our first thread, and we gotta pass in some target for this first thread. So I'll say target is equal to function one. And if you note here, when we write this here, we are just using the function name, right? We're not actually putting the parenthesis here because we're not actually calling the function. We're just setting it here to be a target. So there is no parenthesis here. So let's now define our second thread. So T2 is equal to threading dot thread, and then we'll pass in our target. Our target is going to be function two. And then we'll say T3, our third thread is threading dot thread, and the target of this thread is function three. All right, perfect. So let's see here, now that we have defined these threads, we need to start the thread. So we have defined them, so now we should start the thread. So to start the threads, we just call the thread, so T1 dot start. All right, and so I'm gonna actually comment out these function calls to function one, function two, and function three, and we have T1 dot start. So if I run this right now, thread one should start, and it should just print out one, easy. So if I then do T2 dot start, what will happen? So before when we called function one, and then function two, we saw function one finished, and then function two started. But now with threads, if we run this, you can see we are getting these things running concurrently, one, two, one, two, one, two, one, two, one. So these threads are running at the same time. And of course we can then throw in T3 and start T3. So if we run T3 now, we can see that three is also being printed in here, and so our three functions are being run concurrently rather than sequentially. Awesome, so this is really cool. Maybe this is gonna give us a way to run certain parts of our programs, our chat application, like sending and receiving messages at the same exact time. A few really important things to note here though. So threads can only be run once. So I've defined my thread T1, and so if I start it here, I can't necessarily start or call T1 again. So like if I do T1.start again, let's see what happens. I get an error, it's a runtime error. Threads can only be started once. So if we want to use T1 again, we essentially have to redefine T1. So I'm gonna put a comment here to help us understand. I'll say threads can only be run once. So if you want to reuse, you must redefine, all right? So we'll redefine T1 as threading.thread, and then we'll pass in our target, and so I'll pass in my target again, function one, all right? Perfect, and now I should be able to call T1.start, and then I don't know, I'll just print a message once it's done, I'll say threading rules. So now if we run this, we should see our thread running, our thread running, and then the question is where will this maybe print statement occur, all right? So we started a thread, and so the thread is gonna run, and then where does this print statement occur? So let's run this. Oh, did I have a mistake here? Let's see, T1 is equal to threading, target function one, no attribute. So I think I have a mistake here. Let me just see what this says, function T1 is threading. Oh, I put the word tread. Let me add a thread in here. So let's run this, okay? So let's run this, and so you can see now I'm recalling thread one, and that was not a problem, and you can see here, right, threading rules, it's getting just printed in there, right? It's just getting thrown right in there. So we're calling our first thread, our second thread, our third thread, we're redefining that thread. Everything is running as fast as it possibly can. However, we might want to pause our program and wait for the threads to be done before we print maybe this final statement. Trying to control when our threads run and when our main code is running is something that we might want to do in the future. So to do this, we can simply pause the program, the main program until a thread is done. And so if we look here, I will come down here and I'll say if you want to pause the main program until a thread is done, you can. So let's do that, let's redefine T1. So we're gonna call T1 again, so we have to redefine it, threading.thread, and we'll set a target to be function one. And now what we'll do is we'll call T1.start to start that thread, and then to essentially pause the main program until the thread is finished, we can use the join method. So I'll take my thread T1 and I'll call that join. And we'll say this pauses the main program until the thread is complete. So now what we should hopefully see is we're gonna have, we got lots of threads running. Maybe I will comment out some of these threads just for right now. So we'll run our thread and then we're gonna redefine it, run it again. And once that is done, at the end now we should print threading rules. So let's see if this works, if we're pausing it correctly. And we most certainly are. So the main program was on pause until the thread had finished, whatever it was trying to execute. And then we went back to running the main program. Awesome, so I think this is a nice introduction to threading and we're gonna see how we can use this threading module to really help us instill some of the concepts of a chat room that we had talked about in our earlier video. I can't wait to see you in our next video where we begin building that chat room application. And we'll see how we can have many people communicate back and forth as many clients attack or connect to a single server. So I'll see you in that next video. With the fundamentals of threading at our disposal we now have a way for parts of our programs to run concurrently rather than sequentially. And this is gonna be huge for us in trying to make a chat room app as you can imagine our server or client scripts are going to have to be listening for connections, receiving information and sending information all at the same time. We can do just that with threads. So let's start with the basics on both our server and client scripts. So we're gonna open up two new files here and save them in our new folder and I'll call them server.py and client.py. So we'll make a new Python file and we'll say server side chat room and I'll save this in. We're in our terminal chat room folder and I'll just save this as server. So server.py and we'll make a new file here and we'll make it a Python file and I'll say client side chat room. Yep, perfect. And I'll save this and I'll save this as client. So it'll be a client.py file. Excellent. So let's start with the server side. So over here we're gonna begin by importing the socket and the threading module. So we want both of them in here. So we'll say import socket and comma threading. So that will bring both of those modules in so we have access to their functionality. Next, let's define some constant variables that we are going to use across the program. So we'll say here define constants to be used. And again, I like doing this because then if we want to change these later on, all we have to do is just come to the top of our code here and we can create those changes. So the first thing that we're gonna need is we're gonna need our local IP address and we'll use that as the host IP. So we'll say host IP is equal to socket.gethostbyname and then in here we'll pass socket.gethostname. All right, perfect. Next we'll need a port address. So we'll say host port is equal to, let's use one, two, three, four, five again. We'll say one, two, three, four, five. We'll use an encoder. So we'll say encoder is equal to utf8 and we'll specify a maximum byte size. So byte size, and again, we'll just arbitrarily pick 1024 right now. We are not really worried too much about that for the time being. So with those defined, let's now create our server socket, bind it to a specific IP address and port address and then we'll begin listening for incoming connections. And so just like we have been using in the past, we're gonna use the IPv4 and TCP protocols for our socket. So we'll put a comment here. We'll say create a server socket and we will say server socket is what we'll call it is equal to socketmodule.socket and inside of here we're gonna pass in our two protocols. So socket.af underscore inet. That's IPv4 and then socket.socstream. There is, oh, all capitals. There is our TCP connection. Now that we've created this socket, we need to bind it to our specific IP and port that we've specified here. So we'll say, all right, let's take that socket, we just created server socket.bind and in here we'll pass as a tuple, our host IP and our host port. All right, wonderful. And then lastly, because we are listening, we want an incoming connection, we have to listen for that incoming connection. So server socket.listen. All right, and so that looks like it is set up perfect. So the last thing that I'm gonna do here is create essentially a couple of blank lists that we are gonna use to store information about all of the various clients that connect to our chatroom. So the first thing that we'll store is their socket information. You know how when we get a connection, we get the socket that we're as just connected. So we're gonna store those in a list and then we'll also store the name of maybe the client that's connected. So whether it's Mike, Mary, Bob, Joe, et cetera. So we'll just put a comment here. We'll say create two blank lists to store connected client sockets and their names. So we'll call our first one client socket list and that'll be initialized as a blank list and then we'll call the next one client name list. And we'll initialize that as a blank list as well. Perfect, so these are gonna be helpful for us as we kind of move forward in building out this program. So while we're here in our server side script, let's outline some of the functions that we're gonna need for our chatroom server. So you remember, we're gonna use threads here and so threads have to target specific functions and so we're gonna write the function definition here to begin with. So first we can kind of think of this chatroom as different clients talking to each other. I'm sorry, we can't think of this chatroom as clients talking to directly one another, right? Rather, all clients are gonna talk to the server and then the server will essentially forward messages to the other clients, okay? So the server is gonna serve as like an intermediary between all of our connected clients. Messages are gonna come into the server and then the server is gonna route those messages to their specific location, the specific client that they're supposed to go to. So this should hopefully make sense because our clients are not connecting to other clients. They're connecting to the server and every single client is connected to the same server. So our server needs to be able to receive an incoming message. It needs to receive, in fact, it just needs to receive any number of incoming messages and it needs to be able to broadcast or send those incoming messages to all of the clients that are currently connected. So let's outline a function for like each of those functionalities. So first we'll do a broadcast message function which will take in one parameter, a message that is to be broadcast. So we'll say def broadcast message and it'll take in one parameter, a message that is to be broadcast. So we'll put a quick doxtring here kind of describing the functionality of this. We'll say send a message to all clients connected to the server. And then we'll simply just say pass here for right now. We'll worry about writing this later on. Next we'll have a receive message function that will take in one particular parameter. It will take in a client socket that we are trying to receive a given message from. So we'll say def receive message and we'll pass in here a client socket. And so in here we'll just put a doxtring again, receive an incoming message from a specific client and forward the message to be broadcast. So we'll add that in here. And for right now we'll just say pass. So you can imagine if you think about our previous server scripts, the server waited for an incoming connection and when that incoming connection occurred we accepted it and we got the socket of the connecting client. So you can imagine every time we have someone connect we are going to run this receive message function in a thread and we'll pass in the socket that just connected. So we're always going to be listening for incoming messages here. And lastly we'll have one that is connect client. So we will have a function here that is gonna connect a given client. So, and this will take no parameters. So we'll just say def connect client, no parameters in here, but our doxtring will say connect an incoming client to the server. So you might imagine that we're gonna have a thread where we're always listening for incoming connections. So for right now we'll just say pass. So this looks pretty good here. We've got our functions kind of mapped out nicely. We've got a good setup here for the server script. Let's head over to our client script right now. So I'm just gonna save this and we'll come over to our client script. Inside of our client script, the first thing that we'll do here initially is we will import the socket module and the threading module. All right, so now we have access to them. And the next thing that we'll do is we'll define our constants in a similar manner that we did for our server. So I'll just say define constants to be used. And so I'll have a destination IP socket dot get host by name. And then inside of here I'll do socket dot get host name. All right, perfect. Then we have a destination port and I'll set that to be one, two, three, four, five. We'll do an encoder encoder and we'll set that to be UTF-8. And then we'll specify our byte size just to be 1024 because we're not really too worried about that for right now. All right, good. With all of these defined, let's now create our client socket. So we'll say create a client socket and we will use IPv4 and TCP again. And so we'll call this client socket is equal to socket, the socket module, and then we'll call socket. So socket dot socket. And then in here we'll pass in our two protocols. So socket dot af underscore inet and socket dot sock stream. Oh, I think I made that same mistake before. There we go. All capital letters on those things. Now that we've had this client socket, we are going to connect to the server socket that is at our specified destination IP and destination port address. So we'll call the client socket client socket dot connect. We'll call the dot connect method. And inside here we're gonna pass a tuple that specifies where we should connect to. So we'll say destination IP and destination port. Okay, so that I think is pretty great here for the setup. Why don't we just quickly outline what the client needs to do, similarly to what we did with the server. So the client, if you think about it, the client needs to be able to send a message to the server, which is then eventually gonna be broadcast for all clients to read. And then it also needs to be able to receive a message from the server whenever the server is broadcasting another client's message. So really, we just need two functions here. So this is easy enough. Let's outline this right now. So we'll say def send message and we'll say no parameters and we'll just put a doc string here, send a message to the server to be broadcast, to be broadcast. All right, perfect. And we'll pass for right now. And then we'll say def receive message and we'll put a little doc string in here receive and we'll say an incoming message from the server. And we'll say pass here. And I'm gonna simply just save this right now. Okay, so I think our setups here are complete. So our client socket is created. We've got some functionality we'll work on. The client should be able to send a message from the server and it should be able to receive a message or send a message to the server, receive a message from the server. And our server is all set up here and the server should be able to connect a given client. Once that client is connected, it should listen for incoming messages. It should receive those messages. And then once it gets a message, it is going to broadcast or essentially send that specific message to all other clients connected to the server. So you can imagine if one client types, hey everybody, how's it going? Every client connected to the server will then get that message. All right, I think this is a great place to stop. We got a nice kind of skeleton here set up that we can kind of fill in in our next couple of videos where we will begin coding this functionality. So I'll see you in that next video.