[Music] what is going on guys welcome back in today's video we're going to cover the fundamentals of sockets now on this channel we have a lot of different videos that are networking related for example tcp chats or zoom clones or streaming audio data streaming camera data and so on but we don't have a video that covers sockets in detail on a fundamental level so what is a socket how does it work how do we create it in python what are different parameters that we pass so what does for example afinet mean what does sockstream mean and so on so what are the different protocols that we can use and in this video we're going to talk about sockets on a fundamental level and we're going to build a basic server client system client server system in python so let us get right into it all right guys so we're not going to start with the coding right away we're going to start with some theory and this is because i want to make sure that you understand some basic concepts first so for example what is a client what is a server what is a client server architecture what are ip addresses what is the difference between a local ip address and a public ip address what is a socket what are the different protocols that we can use what is the difference between tcp udp and so on um so we're going to talk about that here first and then we're going to get into coding and for this i have on my second screen here a couple of notes i don't want to rely on them but maybe i'm going to look at them a couple of times to make sure that i don't miss anything so that you get a full explanation so don't be uh confused by that we're going to start with something very simple which is the client and server architecture i'm just going to write down client server here uh what is the client what is the server and the client server architecture then is just basically the way uh that we structure a program with clients and servers so um a very basic idea of a client and server is we have i don't know some central server here oh sorry some central server here which we're just going to call server and then we have multiple clients connecting to that server so let's say we have a pc one here we have a pc2 here we can also have a phone for example doesn't have to be a computer we can have i don't know a ps4 and some smart devices some smart refrigera smart refrigerator for example or anything that can communicate with the server and then we have uh these connections so pc1 for example can make a request to the server to talk to pc2 and then pc2 gets a message so for example i can say hi and it says hi to pc2 i can do that like that the important thing is that i'm not connecting so pc1 is not sending the message to pc2 but pc1 is sending the message to the server and the server is then sending it to pc2 or we can also just broadcast it to pc2 uh to the phone to the ps4 by the way i missed the phone here there you go so this is something that we can do with the server uh and of course this server can have different purposes it can be a chatting server so we can just say this is a server for a message exchange so this can be a chat room and everyone can send messages that are broadcasted to everyone else or it can be a gaming server for some i don't know some online game that is cross-platform so i can play it on pc with someone that is playing it on a ps4 with someone else that is playing it on the phone and this server is managing all the action so for example if this person in the game walks somewhere everyone else needs to know as well and then this person walks somewhere and everyone needs to know as well so just a basic central piece as a basic central um entity that processes requests with respond gives us responses so for example i'm sending something i'm receiving something this is also what server stands where we have the client the client is requesting something and the server is responding it's serving the client and giving him giving the client an answer so this is a very basic explanation of what a pc and a server is now let's get a little bit more detailed because in reality or in computers we always have some addresses uh we're not going to get too deep into the different models because there is a standardized oc model with layers so we have basically layer one layer two layer 2 is like mac address and layer 3 is then ip address so we're not going to talk about that in too much detail here but what you need to know is that essentially communication happens or the addressing not the communication itself the addressing happens with so-called ip addresses i'm sure you have heard of that and let's say this here is a local area network so a lan this is a local area network this is not the internet this is all in one home with one router and so on um and each of those devices have a certain ip address so for example this could be 1 9 2 1 6 8 0 15 for example this is the ip address the pc could be 192 16808 for example and so on those have similar ip addresses and whenever i want to do something for example i'm hosting the server on this ip address and this computer is connecting to that ip address those are the relevant ip addresses so the server is hosting the server on its own ip address here and if the computer wants to connect to that server it has to connect given that ip address and of course we're going to see later on we also have ports so we're not only connecting to 192 168 now we're also specifying a port number for example i don't know 90 90. uh you can think of a port number as a door to a room so let's say maybe not the best analogy here but let's say we have a house and the house has certain rooms so we have a room here we have a room here and a room here and a room here so this room for example could have the ip address 192 168 0 15 but it has different entrances so this is entrance a this is entrance b this is entrance c so different doors that i can use to enter this room and those different doors can be controlled by i don't know security or something but basically the door i use is the port i use so i get to the same room i get to the same location to the same ip address but i'm using different ports so this is important if i want to enter with port 1990 for example the server also has to listen at port 9090 for incoming connections otherwise it's not going to open the door for me so this is some very basic stuff now we're going to [Music] to expand on that because this is in a local area network what we're talking about here is a so-called local ip address this is a private ip address you can get this ip address and we're going to look at that in a second on windows by typing ipconfig into the command line or on linux and mac if you type if config you're going to get that ip address this is a local ip address that you have in your home so in your home you have your ip address and this is only private if i show you my local ip address so let's say this was my local ip address you're not going to be able to connect to me via the internet even if i'm hosting something and even if my firewall is open and everything is fine you're not going to be able to connect to me because of the fact that this is my local ip address you can only address me with this local ip address if you are in the same local area network so you're not able to address me with that ip address if you're somewhere out there for this we have a so-called public ip address so let's say this here is my local area network so this is my home network lan and somewhere here i have a router uh let's just say this is a router and it's connecting me to the internet okay in the internet i have a different ip address i don't have those local ip addresses because the good thing about local ip addresses is uh there are three types uh three classes we have 192 168 we have 10.0 and so on we have different uh types but the good thing is chances are that if you type ipconfig or if config you're going to have an ip address with that uh pattern so you're going to have 192 168 and then some numbers so everyone has or multiple people have those ip addresses they're not unique in the internet if you address me on my p address it's going to be unique so um for example let's say in the internet i could have uh after a so-called network address translation after so-called um port address translation sometimes also called pat we're not going to get to the details here i have a different ip address so all my local ip addresses are in in the case of port address translation uh translated to one public ip address so let's say imaginary ip address this could be something like seven six point two eight point four four point i don't know two one one it's not going to be in my ip address so this is the ip address of someone else uh don't think that this is in any way a relevant ip address but this could be my public ip address so if i give you that ip address this is what you have to address me with if you want to connect to me so let's say you're also in the internet you have another router here and you have your local area network with your devices computers phones servers whatever if you want to make a request to my server that i'm hosting on this local ip address you need to address me using that ip address here so this is my public ip address for example this is my local ip address now the important thing is and this is what we always need to keep in mind when we're creating network applications in python for example the server has to be hosted on this private ip address so when i say server.bind which is the function we're going to use later on for binding the server to a certain host and port i need to specify my local ip address however if you are not part of that local area network here if you are part of some other network in the internet and you want to connect to my server even though it's hosted on that private ip address you need to connect to the public ip address this is important so this is the basic uh thing that you need to know when you're communicating using sockets and using uh networking protocols via the internet all right so you should now have a pretty good understanding of what an ip address is which one to specify when connecting which one to specify when hosting and you should also understand what a client server architecture is so let us now talk about sockets because this video is about sockets let's not forget that and what sockets are is just communication endpoints so if we have a point a that wants to communicate with a point b uh through whatever way a socket is basically just a communication endpoint so this is a socket and it's communicating with the other socket it doesn't have to be an internet socket so we can have a communication that is not based on the internet so for example we have sockets for an operating system or on an operating system level we have sockets that are bluetooth sockets so for example uh for those of you who have used sockets in python we're going to talk about that in a second as well but uh when we specify a socket we always specify like uh socket.af underscore inet which basically says this is an internet socket but afinet is not the only thing that we have we also have for example af bluetooth right this is a bluetooth socket so a socket does not have to be an ip socket or an internet socket it can also be a bluetooth socket an infrared socket it can be an operating system level socket so it's just a communication endpoint it doesn't necessarily have to do anything with networking um having said that in this video we're going to mainly focus on uh internet sockets so uh we're going to mention the different or we already mentioned the different sockets like bluetooth infrared and so on but we're mainly going to focus on the internet sockets which are which are specified with af inet and here we have afinet for ipv4 which is ipv4 and we have af inet 6 for ip version 6. but again we're going to mainly focus on ipv4 so this is what we use the sockets for in this particular tutorial we're going to talk about those but in the context of an internet socket we still have different sockets so when we specify sockets in python we first specify afinet for example but then we also need to choose is this socket of type sock underscore stream or is it of the type sock underscore d gram which stands for datagram and the difference here is in the context of an internet socket sock stream is tcp and sock dram is udp those are two different protocols uh now let's see if i remember what tcp stands for i think it's a transmission transmission [Music] control protocol i hope this is right i hope i don't uh protocol i hope i don't talk any here and udp is a user datagram protocol now if i made a mistake here you're going to see it somewhere here but i think this is a transmission control protocol and this is a user datagram uh protocol and those two protocols are what we're basically using when we're communicating so if i have a chat i can use tcp to transmit the messages or i can use udp to transmit messages which one we're using depends on what we're trying to do here but those are two different things that we can specify we specify a socket in python for example it's the same in c by the way as well when we specify a socket we can choose okay is this an internet socket is this a bluetooth socket is this an infrared socket and then uh when we have chosen that we can still choose is this a stream socket or a datagram socket not only for the internet sockets in the context of internet sockets we have tcp and udp but also if we choose something else we can choose stream or datagram and then it's going to choose the necessary protocol so we don't need to specify the protocol per se it's going to uh to choose the right protocol we just have to specify do we want sockstream or sockdgram those are just types and the combination results in a protocol the important thing is that you want to choose sockstream whenever you are interested in let we use a different color you want to choose sockstream whenever you're interested in a connection based socket a connection based socket basically means you have this point a and you have this point b and you want to establish a a connection and you want to exchange messages and once the connection is done or once the exchange of messages is no longer needed we terminate that connection that is a connection based uh socket and then on the other hand we have sock dram which is a datagram uh based socket where we basically say okay i send a message to b and that's it and b sorry b sends a message to a and that's it so we have those individual messages uh as datagrams instead of a connection within exchange that we can terminate uh this is basically the difference here so some differences in general between tcp and udp let me just get rid of all that here come on uh some difference in some differences that we have here for example tcp is what you want to choose if you want to have a reliable connection because tcp is as we already said connection based connection based it's reliable because you can find you can detect packet loss so if you send something in tcp you're going to get the response that it was received so you have um you have the confirmation that the packet was actually sent and it arrived whereas udp you just send it and if it is lost it's lost that's it so we can detect packet loss here it's reliable it's connection based it's sequential so basically in tcp uh you send one message another message another message another message and another message and that is the order that the other communication endpoint is going to receive the message or the packets in so one two three four five in udp that's not the case in udp you send the packets and maybe they're going to arrive in a different order you're just sending them maybe they get lost maybe they arrive in a different order um so you don't have this sequentiality here uh it's also a byte stream this is important tcp is a byte stream and we have it it keeps up keeps up a connection it keeps up a connection and has a message exchange in that connection and it terminates when we don't want this exchange anymore so this is tcp on the other hand well let's actually not delete that let's just add it to the right here on the other hand we have udp udp uh and udp is not reliable it's datagram based so it sends exactly one datagram and that's it and if you want to answer you got to send a datagram as well and if you want to send a second message you send a second datagram but they're not related they're not sequential so i can send one two three and the other one is going to receive two three one for example because they are not connected they're not linked they're not sequential uh there's no order no guarantee whatsoever so let's write that down no order no guarantee uh and no noticing of lost packets and so on so you might be asking why the hell should i use udp if tcp is so much more reliable and sequential and it has a connection all that the thing that is good about udp is it is more real time doesn't mean the tcp cannot be real time but udp is faster you can just say it's faster and it has less network and pc stress because we don't need all these controls we don't have a connection we don't have all these um these detections we don't have all this reliability and this reliability of course comes at a cost udp is just faster real time and if some packets are lost who cares so the question is when should you use udp and when should you use tcp um tcp in general you want to use it when you cannot handle when you cannot allow for packet loss if you want to have what you have at point a you want to have at point b and if it is not there you want to know that so you want to resend packages and so on for example if i'm transmitting some text or if i'm transmitting an image to you it doesn't matter if it arrives one or two seconds later but i want the full thing to arrive at your point so i'm going to use tcp whereas if we have a real-time video connection or audio connection if i'm streaming some audio streaming some video or if we're playing some games and not every single bit of data is important because just because we can lose packages it doesn't mean that we will lose all the packages all the time in udp it just means that some packages can be lost and they're not going to be resent unless we implement something on top of that but if we can handle packet loss and we want to have the best real time experience possible we might want to go with udp otherwise we're going to go with tcp probably all right so as a final example before we get into the coding i want to mention for example that skype which is used mainly for video communication and audio communication is using udp when it comes to the actual call so if we have a person a and a person b and they're talking to each other so this is the the actual call as far as i know with the research that i have done this call is running via udp because it's more real time and because we can handle packet loss however the actual call request so basically a calling b and b answering the call this whole whole exchange here is happening uh via tcp so a is calling b and b says okay yes i want to get on a call with a so this is happening via tcp also the whole message exchange and the images and the emojis everything is happening via tcp but the actual call is happening via udp as far as i know so no guarantee that this is 100 correct but this is first of all how i think skype does it how i read that skype does it but even if it is not exactly how skype does it this is definitely a scenario that makes sense uh besides that for those of you are interested uh vidstream the library that i have written is in the alpha alpha alpha version so it's not a good library yet but we have used it in a couple of videos for example the zoom clone um vidstream is running on tcp i'm not saying that this is necessarily good but bitstream is running on tcp all the video streaming the audio streaming is running on tcp uh maybe i'm going to change that in the future because it works but maybe it's more efficient if we use udp so maybe i'm going to rewrite the whole module and make it a little bit more efficient with udp over time but this is just the fact that i wanted you to know you can also stream video with tcp it's not impossible all right so let's go ahead and implement all that knowledge into python now uh and for this we're going to start by creating a new file which we're going to call server dot py and in this server the first thing we're going to do is we're going to import the socket module so we're going to say import socket because this is what we need in order to work with sockets and this server is going to be the server obviously of the client server architecture and we're then going to also have a client.poi which is going to be able to connect to the server uh and the server is going to be running all the time the clients are going to connect to the server and whatever we want to do with that server can be done uh without a problem so we're going to start by saying socket equals socket and you need to get used to that whenever you work with sockets you're going to use the word socket quite often so we're going to say socket equals or maybe socket is not the right uh term here let's say server equals socket dot socket and then socket dot and here we need to specify what kind of socket we have so we say server equals socket socket and then socket dot and we need to specify af underscore and as you can see we have a bunch of different socket types here we have very uh very different types for example here as i already said bluetooth what we're interested in is inet so af underscore inet and then we specify socket dot sock and then we have sock stream or sock dram we're going to use sockstream in this video so we're going to build a tcp socket here we're going to use a tcp socket here and this is now a socket but we don't know what this socket is going to be used for it's nowhere to find that the socket is going to connect to something or that is going to be hosting something so we don't know yet that this is going to be a server in order to make clear that this is a server we need to bind it to a host and a port and we're going to define host and port up here as constant so we're going to say host equals and as we already talked about we need to specify the private local ip address here no matter if we're awaiting some internet connection or if we uh if we do this in a local area network we always need to specify a private ip address now if you don't know uip address you just open up the command line so cmd you can do that by just clicking on start and sync cmd and then command prompt and in here you type ipconfig and don't be confused by all the different adapters for example one thing that you need to keep in mind is if you have virtualbox installed for virtualization purposes you're going to have an own adapter for virtual box hosting and then you're going to have an ip4 address here that is not the address that we're actually interested in we want to know what is the ethernet adapter address if you're using ethernet or alternatively you have wireless lan which is basically just uh your wi-fi and then you want to go to ipv4 address and this is the address that you're interested in so 192.1680206 in my case maybe something else in your case it doesn't have to start with those two this is one possibility uh how a private ip address can start with the other other is um i think we have 10.00 whatever and then we have something with 172 and i don't want to continue because i don't know what the rest is but we have these three classes basically uh and once you know your ip address you can just manually type it in 192 1680206 or what you can do in python but it doesn't work if you have a virtual box adapter at least not in in that way uh because it's going to take this ip address if you do it but what you can do in python is you can say um host equals socket dot get host by name socket.gethostname and by doing that you automatically get your private ip address dynamically so if you run this on a different computer you're going to get the private address of the different computer of the other computer however as i said if you're using virtualbox it's not going to give you that ip address it's going to give you the virtual box ip address which is a problem so i do it manually here and then what we need to do is we need to specify a port when choosing the port number it's important that you don't choose a well-known port or a reserved port so you don't want to choose 80 for example which is for http you don't want to choose 22 which is for ssh you don't want to take any of those lower numbers that are reserved for common uses but you want to take something like 90 90 for example i'm sure someone is using 9090 as well but you just pick something that is not too well known and if 90 90 does not work you take 9999 for example whatever it's important that you have the same port in the client and in the server um by the way if you're just interested in hosting this on this computer only you can also specify a local host here uh or also one two seven zero zero one which is also localhost but if we're doing this in a local area network or in the internet with different computers you want to specify your ip address here your private ip address so then we just have to say server dot bind and we don't pass host import we pass a tuple of host and port so inside of those parentheses again we have parentheses host and port so server bind host port and then what we do is we start to listen for incoming connections so we say server dot listen and we can optionally we don't have to if we want to limit the possible connections that are waiting for accepting or for acceptance we can limit it by passing a five for example so this basically means uh how many unaccepted connections do we allow before we reject new ones so uh when we connect to that server we can accept it or not but until it's accepted it's waiting basically and if more than five connections are waiting we'll just reject new connections we don't have to do this but this is one thing that you can do so server.listen and then what we can do is we can just say while true basically an endless loop and now we can accept connections this is unconditional we just accept all the time every connection that we have and the return value of the accept methods so we say server.accept is two values so we have first of all another socket that we can use for the connection so i'm going to call this communication socket and the address of the incoming connection this is what we get from the accept method so basically what this method is doing if no connection is coming in we're just waiting here we're doing nothing we're waiting for connections to come in now when a client tries to connect to that server this accept method triggers and it returns the address of the client that is connecting and a socket that we can use to talk to that client it's important that you don't think that we can use the server socket to talk to the client we use this socket here to talk to the individual client so the idea is that for each connection we get a new socket that allows us to communicate with this client because this socket here is just for accepting connections it's not for the communication the communication socket is this socket that is returned from the accept method it's very important uh so when we get a connection we can just say print connected or uh yeah connected to address so that we see the ip address um and then we can say message equals and we get the message from the client of course if we receive a connection or expect to receive not a connection a message if we expect to receive a message from the client we're waiting for that message now the client since we have the same uh scenario the same use case the client should also send a message if the client doesn't send a message we're just going to wait and not receive anything so it's not going to work whenever we try to receive the client has to try to send and whenever we try to send the client has to receive so we say message equals communication socket dot receive like that recv and here we specify the buffer size so how many bytes usually we take something like uh 1024 bytes uh so we receive that and then what we do is we decode it because uh when we send messages via sockets we need to encode them so that there are byte streams because we don't want to send just strings we have to send byte streams so we encode them with a certain encoding and we decode decode them you can just use ascii for example or you can use utf minus 8 whatever you want to use so we decode that and we can print f string message from client is and then just a message there you go and then we can send a message back to the client if we want to so communication socket dot sent for example um and we're going to send got your message thank you now as you can see this is now uh not not valid or it's underlined because we have to encode it because we cannot send strings we need to send bytes so we say encode utf -8 and once this is done we can close the connection so we can say communication socket.close we're done with you you don't have to close it you can also keep it up and send more messages if you want to uh and then we can say print connection with address ended for example so this is basically the server now this server is of course uh not perfect because we cannot handle multiple connections at once this is where we would introduce multi-threading we're not going to cover multi-threading in this video because i have a lot of videos on chat servers on zoom clones just go to my channel and type tcp chat or zoom clone or camera streaming or camera chat whatever you're going to see how this is done especially in the tcp chat i do it manually without using vid stream so you can just go to tcp chat and you can see how you can handle multiple connections this video is about socket so we're not going to get into threading too much but this is a basic server so here we can receive a message we accept connections we receive messages we print them out we send a message back and we close the connection a very basic server so now we need a client that is going to send something to that server so client.py is going to be the second file and the client is going to be quite simple we again import socket and as a host this time we specify the ip of the server we're not interested in our own ip we're interested in the ip of the server now since i'm running this on the same computer obviously it's going to be the same so in this case 192 1680206 if you're not running this on your own computer you need to uh or on the same computer the client needs to specify the host of the server so let's say i have a second laptop here and this client is running on the second laptop the host i specify here needs to be that host no matter what the ip of this computer is however as we already talked about if this is not in the same local area network if this is in the internet so not in the lan but in the internet if this is the case we specify this host here but here we need to specify the public ib ip address so where do you get the public ip address through services like for example myip.is you just visit that web website and you know the ip address and you can ask the guy okay what's your public ip address let me know that it this guy says for example i don't know it's eight seven point two three four point nine nine point one two for example and then you connect to that host uh of course the firewall needs to be open and all that stuff but this is important you specify the private host for hosting and you specify the public ip address in this case it's the same because we're running this on the same computer there you go and the port has to be the same as well so 90 90 in this case then we create a socket again it has to be again a socket.socket with socket.internet afinet and it is also a tcp socket there you go but this time since we're not hosting but since we're connecting we don't call the bind function we call the connect function so we say socket.connect and we pass a tuple again so inside of the parentheses we put parentheses and we specify the host and the port that's how it's done and now we're connected to the server if the server accepts us so this sends a request to the server the server has to accept it and once it's accepted we go past that statement to the next statement and this is going to be just socket.send hello world for example we encode that of course utf-8 uh and then we just print whatever we receive from the server so socket.receive 1024 bytes and that's it so as you can see here we have only one socket we connect and we send with the same socket here we have a socket for hosting and then an individual socket that we use for the connection with the individual clients so this socket here is just for running the server listening for new connections and maybe accepting them as you can see here and once we accept them so once we have a connection here this is one end point for the client and this here not this year this here is the other end point for the server for the communication so let's see if this works we're going to open up cmd we're going to navigate to desktop to programming to python to neural nine and we're going to run the server here we're going to say python server dot py server is running nothing is happening obviously and then we're going to open up command line again cd desktop cd programming cd python cd neural nine and then we're going to run a client and as you can see let's just split this here you can see connected to this dip address message from client is hello world and here got your message thank you oh we didn't decode that which is why we see this byte here it's not really a problem but if we want to get rid of that we just say decode utf -8 and then this is also no longer a problem so let's rerun this we can do this again or maybe it's closed already so let's run this again cmd desktop programming python girl 9 python client.py there you go we got a problem here string has no attribute decode why is that of course it has where is that 18 in server dot py oh yeah it doesn't have that because i entered this at the wrong position i think here we need that dot decode utf-8 because here we print what we receive okay now it should work um so now if i run the server again and if we run the client again there you go you have no byte here and we have all the messages here all right so that's it for today's video hope you enjoyed i hope you learned something if so let me know by hitting a like button and leaving a comment in the comment section down below and of course don't forget to subscribe to this channel and hit the notification bell to not miss a single future video for free other than that thank you much for watching see you next video and bye [Music] you