Network Programming with Python Course (build a port scanner, mailing client, chat room, DDOS)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what is going on guys welcome to this python course for network programming in today's video you're going to learn network programming principles in python taught on four different projects so we're going to do a mailing client we're going to learn how to automate mails we're going to learn how to do a ddos script so a little bit of penetration testing there we're also going to build a threaded port scanner which is essentially just a port scanner on steroids so it's going to scan multiple ports at a second at the same second and we're also going to build a tcp chat that allows you to chat with the server and multiple clients connected to the server at once so i hope you enjoy this video and let's get right into it now let's get started with the code the first thing we need to do is we need to import the smtp library of python smtp is a protocol that we're going to use to send mails because what we need to do here is we need to take our script and log into an existing mailing account so make sure you have one you log into an existing mailing account and then use the smtp protocol with your python script in order to send mails from that account to other accounts so you cannot just send mails directly from the python script you use the python script to log into your existing mail account and then use the smtp protocol to send mails from there um so this is what we're going to do and for this we need to define a server the server is defined by smtplib.smtp and here you have to specify the smtp server and a port and the port we're going to use is 25 for smtp and the smtp server address is usually something that you can find out by googling so you just type in smtp server gmail smtp server yahoo whatever provider you're using so smtp.gmail.com for example is the one for google it's a very uh basic format actually you always write smtp dot most of the time it's just going to be dot whatever your provider's domain is in my case i'm using a an austrian uh provider here where i'm hosting my website which is world4you.com so smtp.world4you.com is the address of my smtp server here we're off the smtp server of my provider and once we have that we're just going to start it to start the whole service here by calling the ehlo command so this is the function you need to call to start the whole process and now the next thing that we need to do is we need to log into the account so you have your smtp server a gmail or whatever it is and then you just log into your account and to do that of course you need the information first you need the email and the password and i would never recommend saving the password clear text in your um script because what you essentially need to do is you need to say server.login and then you know you have your mail here mail at mail.com whatever and then your password here password123 whatever it is uh you can do it like that if you want if you're just using the script with a crappy mail account that you don't need just for experimentation you can do it like that but i would not recommend it what you should usually do is you should save your your password encrypted in a text file then load that text file decrypt it and then use that password for this tutorial i'm just going to save the clear text password or actually save the clear text password already in a text file and i'm going to read it here so that you as a viewer are not able to see it so what i'm going to do is i'm going to see with open i'm going to open a text file stream uh with open password dot txt in reading mode sf and we're going to say password equals f.read so now i have the password that i saved in this password txt file i now have it in the script and i'm going to say server dot login and now you have to specify your mail so whatever maybe yours is alex gmail.com whatever it is in my case i created a separate email for this tutorial so mail testing at neural9.com and the password is the one we just loaded so this is how you log into your server into the smtp server into your mail account and now we can start creating the message now before we can start creating the mail message what we need to do is we need to import some additional libraries because what we're going to do is we're going to create a message a mail consisting of multiple parts of attachments of messages of headers uh and for this we need to import some additional libraries so let's start with from email import encoders which is something that we're going to need later on this video not not yet and also let's say import not frozen set from email import mime text which is the ordinary text that we're going to use um actually from email dot mime dot text import mime text then from email dot mime dot base we're going to import mime base which is what we're going to use for the attachment and then for the whole thing we're going to use mime dot multi-part import multi-part um that's it and now we can start creating the message using these libraries here so the first thing that we're going to do is we're going to define the message as a my multi-part and we're going to define the header and the header is essentially consisting of a from to and a subject so we're going to say message equals or actually message from equals because message can be treated like a dictionary we can just say okay message from equals and here we're going to say neural nine or your name whatever you want you can put here um all kind of creative stuff and we can say two and here you usually just specify the target email in my case i'm going to use a 10 minute mail but i'm not going to use the 10 minute mail domain because the 10 minute mail domain for some reason it's not able to receive attachments i tried at least when i was experimenting with my script i couldn't receive attachments there so i'm going to use a german spam mail provider which is providing 10 minute mails and the domain is called spammel.de so i'm going to just say mail testing at spamo or actually this is probably not that that intelligent because my mail is already mail testing let's say uh test mails at spammel.de you can use a different one you can also use your existing email a real email i'm just going to use a spam mail for this video then we're also going to say subject equals um whatever you want it to be just a test this is essentially what you're going to see once you receive the mail in the subject and uh that's essentially it now you can specify a text for your message and i usually do this in a file so we're going to create a new text file here we're going to say message.txt and here we're going to just write our mail message hello world this is a mail sent with python uh subscribe to neural nine always got to do this as we're used to it to it already from the other videos kind regards uh neural nine there you go then you have the message here and what you do then is you just load the message the same way you loaded the password if you loaded it so with open message dot txt in reading mode s f we're going to say message equals f dot read that's essentially it and this is something that you just need to attach to the message object here so message.attach which is not the attachment we're going to add the attachment later on so we are not adding oh sorry not text.txt you're not adding the um txt file to the mail you're adding it as a text and we're later on also going to add an image as an attachment so what you need to do now is you need to attach mime text and you're just going to pass the message here and you're going to attach it as plain text so this is how you add a header and a text to your message object now one more thing that want to do before we send the actual message is you want to attach an image to it so in this case i downloaded the royalty free image from pixabay uh you can also use google images if you're just using it for your personal experimentation you're not going to get sued for that so i just picked this coding.jpg file from pixabay because i'm doing a video and i shouldn't be using copyrighted images here um however you get this image put it into the same directory and then you specify the file name file name in this case coding.jpg or essentially the file path if it's somewhere else you can also specify the whole path and then we're going to open up attachment equals open we're just going to open a file stream of this file name and now we're going to open it in reading binary so we're not going or reading bytes we're not going to open it up in reading text mode but in reading byte mode because we're using um we're working with image data here not with text data anymore uh so the next thing is we're going to create a payload object so we're going to say p equals and now we're going to use this mime base object so we're going to say minebase and here we're just going to start a so-called don't ask me what it stands for it's a application and then it's called an oc t e t stream which is essentially the scene uh the stream that we're going to use to uh process this image data here and then we're going to set the payload of this payload to attachment to the file stream dot read or actually like that attachment.read i'm not sure if we even need those parentheses here i don't think so so attachment.read and this is what you set as the payload you just read the content of this attachment with reading byte modes uh and you set the payload now the next thing you want to do is you're now going to use the encoders so we're going to say encoders and code base64 so we're going to encode the image data that we just read and that we set as a payload uh we're going to encode p and then we're going to add a header to p so we're going to say p dot add header content disposition and we're going to use an f string here to say application or attachment sorry attachment semicolon and then file name and now of course we add the file name here which is just file name and this is how you add the attachment of course now the payload the attachment itself has to be attached to the message so i'm going to say message.attach yeah message.attach p and that's how you add the actual payload to the message now the last thing we need to do is we need to say text equals message dot um as string so we finally get the whole thing as a string and this string can then be sent by the server so we're going to say server dot send mail and we're going to send it from mail testing at neural nine dot com to our target what was it test males test male start and we're going to send the message which is the text now this is the whole script and we're now going to test it so now what i did is i created a spam mail on spammel.de it's german don't get confused by that but you can also use any other spam mail provider or you can just use a real mail as a target um in this case i just didn't want to use or show any of my personal emails so i use this spam test mails at spamo.te and now what we're going to do is we're going to run our script so we're going to say run and if we didn't make any mistakes this should now send the email without any errors wow we didn't get an exception i'm surprised to be honest and now let's wait for it and see if we get something here and you get it here just a test hello world this is a male scent with python subscribe to neural nine kind regards neural nine you can also see that uh avas or avest was checking this mail so if you don't want this message to appear just if you're using the same anti-virus software just turn it off and you can also see that there is an attachment in here coding.jpg and if i download it you can see that it's the exact image that we wanted to send so it worked the script worked you have neural nine at an unknown i don't know if we have the male header here somewhere as well but if you're using a normal mail account this should appear as neural nine as uh or your mail not neural nine as in this case mail testing at neural nine dot com uh in this case it says neural nine at unknown i don't know why it does that but essentially it works the subject is here the text is here as a normal text and then we also have the attachment so it worked perfectly fine and that's basically it we're going to code a distributed denial of service script which is basically a script that overloads a website with requests so that this website is not able to offer its service anymore because you're overloading its capacities basically so before we get into the code let's talk a little bit about how ddos basically works um you have one attacker and this attacker chooses a target for example the server of a shop or off a newspaper or something and says okay i want to take this side down so what do i do i send 5000 or 10 000 or 50 000 requests per second so that the server will be overloaded the capacities are not enough to handle all these requests and as an effect of that if a normal user wants to connect to that website it's also not possible because you're getting 50 000 uh requests per second so if i as a normal user as a customer want to visit that website i'm not going to be able to do that because the hacker is already or actually ddos is not hacking but the attacker is actually flooding the server with a request so i cannot visit the site as well now of course you can counteract this by blocking the ip address of the one who's sending all these requests or actually blocking all the ap addressed addresses except for your own and then you know do some stuff in the back end or something but usually that is how it works you have an attacker and this attacker chooses to take down a website by flooding it with requests now first of all before we get further into this video i want to mention that ddos is highly illegal so if you do it do it on your own server do it off the server onto the server of someone you know that gives you permission to do it don't just go ahead and ddos amazon or any other web page because you can get sued and you can't get imprisoned for that so i am not responsible for what you do with this knowledge here it's purely educational i'm not encouraging you to attack certain websites or something so this is just so that you understand how it works how to implement it with python and then you can penetration test your own systems with it but don't go ahead and you know attack some strangers or some websites of other people having said that let's talk about how this is done when you're attacking bigger targets because in year 2010 i think anonymous took down paypal because of the whole julian assange affair but of course the problem is that paypal is quite a big service and if you want to take down paypal and of course you shouldn't do it but i'm just saying if you want to take down a big target like paypal you cannot just go ahead on your own and run a script what you do is you use a so-called botnet so you in fact other computers these people don't know anything about it but you just go ahead and you uh in fact your computer for example my computer just people that don't know what's happening and you're basically having them as your zombie army it's not about harming these people so you're not infecting their computers with a virus deleting their file encrypting their files uh or you know getting information from them like passwords or something you're just using them as your army so you're using them as your soldiers so uh they will probably not uh recognize that you're even uh taking control of them because you know you're not doing anything with them unless you want to attack a target so if you have let's say 50 000 computers in your botnet you have 50 000 people uh for example grandmas or people that don't know anything about coding anything about networking about hacking they're just using their computers but when you say start they start executing the same script as you are so you're basically saying okay i want to hack paypal uh i use my botnet all these 50 000 computers are going to run this script right now and everyone is flooding paypal with 50 000 uh requests per second and 50 000 times 50 000 is a pretty big number and of course what happens in addition to that is this is just one attacker with one botnet and uh in the attack on paypal you had multiple attackers with their own botnets uh ddosing people so this is how they took down people and again i'm not recommending you to do that i just want you to know how this happens and i want you to understand how this works so that you can maybe penetration test your own systems with it or even uh take some counteractions uh security measures based on that knowledge but that is basically how ddosing works so now let us get started with the coding and the first thing that we're going to do is we're going to import threading and we're going to import socket uh socket because we're going to use it to connect and threading because we're going to run multiple threads now one more thing that i need to mention here is python is maybe not the best language to do this because python doesn't support real multi-threading so uh if you're doing multi-threading in python it's not actual multi-threading it's simulated multi-threading so you're basically switching between the tasks as fast as possible but it's not actual multi-threading so you might want to use a different language for that but it still works uh since it's sending a lot of requests at the same time just so that you know what's happening in the behind behind the scenes basically so what we need here first is we need a target and this target is usually an ip address but it can also be a um a domain name because the domain name can be resolved into an ip address uh but what i'm going to do here i'm going to just ddos my own router and i recommend you to do the same unless you have a website on your own so if you have i don't know uh if your name is john stevenson or something and you have johnstevenson.com please don't ddosjohnstevenson.com if it exists but if this is your web page go ahead and ddos that webpage but um other than that just uh keep it in your own network so ddos your router ddos your own laptop run a run an apache server onto your own system and then ddos that if you want but don't go ahead and ddos some other websites it's highly legal again so the ip of my router my inside ip is 10.0.0.138 and if you want to know what your ip is you can just go ahead and say cmd okay and then you say ipconfig and you're going to see uh wireless lan adapter since i'm using wireless lan here um you can see your own ip this is the ipv4 address which is the one that you're using in your own network so this is not a public ip address otherwise i wouldn't be showing you that this is just in my network at home this is my ip address and the default gateway is my router so this is the ip of it um so if you want to ddos your own router you can just go ahead and say uh ddos this ip address here uh it will be probably different in your system or in your network uh however depending on the port that we're ddosing different things can happen so if i ddos on port 22 i'm ddosing the ssh service so the command line service the secure shell service um and the website will still work if i ddos port 80 i will lead off the http port so the web interface might be down so depending on which service i'm going to take down or i want to take down i'm going to attack a different port in this video we're going to attack http so i'm going to say port equals 80 and what we can also do here is we can specify a fake ip for the header however please don't think that you're anonymous just because you specify a fake ip in the header you of course need to use um anonymization tools so you cannot just go ahead and change the http header and then think that you cannot be recognized as a hacker but still it's a nice extra that you can add to your script so you can say fake ip equals and then you just choose an ip whatever it is um let's just choose 182. 2032 and that's just one sample ip that you can have and these are the the things that you need in order to specify the target and also add your own fake information into the header so now we're going to define the actual attack method and this method doesn't look like an attack method because it's basically just an endless loop running uh a socket connection so what we do is we say def attack we need to define a method here so that we can later on refer to that method in the threads and what we do is we say while true basically an endless loop and then we say as equals socket dot socket socket dot af inet which is basically just creating a new socket an internet socket and then specifying the protocol which is tcp so stock stream and when we've done that we just say s dot connect to the target on the port we need to pass a tuple here um and that's basically it now we have to send the header and for this i'm going to copy the two lines from the website just because i don't want to remember the whole format here as i said you can find the text based version on neural nine dot com so if you want you can just you know copy it from the website or type it in manually we just say get slashed and we enter the target then we say specify the http version encode the whole thing and send it to the target on the specific port then we also say host enter the fake ip address encode it and send it to target and port and after that we just close the connection that's basically the whole attack method it's just uh constantly connecting sending closing connecting sending closing over and over again uh but of course this would not be enough we need to run this in multiple threads so what we do is we basically say uh for i in range how many threads do you want to run you can say 500 for example or 50 or 5000 uh what we do is we say threat equals threading dot threat and we basically specify target but this time this is not the ip target but the target function and this is attack and then we say threat dot start and that's actually it that's actually the whole script we just have an attack method we have the uh 500 threads that run this attack method uh when we run this the connections will be made but of course we won't see anything if you want to see how many connections have been made all uh all the time of course this will slow down the script so printing the connections uh printing the amount of connections already uh done will slow down the script so what we can do uh is we could say already uh i don't know attacked or okay not attacked already connected stupid name i know let's say zero what we do then is when we close the connection we just say okay global so that we can access this already connected variable global already connected and then we say already connected plus equals one and i think that's actually it let me take a look oh of course we need to print it sorry and then we can just print already connected um yeah then we can run it and see what happens you can see immediately we have around 500 of course it's way faster if we don't print all the numbers so what we can do is we can say uh if already connected modulus 500 equals zero which basically means every 500 uh connections you can print it what we do is we just say print already connected so it will only print every 500 connections still or did i make a mistake here oh no actually it's that slow so it's probably not a good script at all but still it works um or maybe it's that slow because i'm asking all the time i don't know however basically this is how you do it you define a method that sends a connection in an endless loop and then what you do is you basically run multiple threads at the same time attacking then you have bots or a botnet with computers that all run the script at the same time and then maybe you also have multiple attackers and in the end you take down a service like that uh of course you can again specify different ports then this part here doesn't make a lot of sense but you can also uh try to take down the ssh server or other services whatever but this is how you basically do it you define a method run multiple threads and then you take down a system so that's it for today's video again this episode was purely educational so first of all the script is not optimal you would not use it for an actual ddos attack it's not a good script you wouldn't use it um it's just so that you can get an understanding of how something like this could be done but no one would ever use this python script for a ddos attack first of all because it's slow second of all because it's not really heavy you're not sending a lot of data um but it's just to see how you could do this in python uh second of all if you're using ddos this script or any other script keep in mind it's illegal use it on your own systems i mentioned it two times before but it's very important and you shouldn't you know do any harm with these scripts we're going to create a port scanner in python which is going to allow us to find open ports in servers computers printers basically any kind of host and we're going to use multi-threading to make this port scanner as fast as possible so we're going to run multiple threads so that we can scan hundreds of ports per second now before we start with the video let me tell you that you can find a text based version of this tutorial at neural nine dot com which is a blog post and there you'll also be able to copy the code if you want so if you're interested in that check that out you'll find a link into the description and you can also check out the other blog posts about machine learning programming and so on this page if you're interested in them so let's get to port scanning now first of all why scan ports why are we interested in open ports we're interested in open ports because an open port especially an unnecessarily open port might be a security gap and we always want to find security gaps either in our own networks to make sure that our network is secure enough or if we have bad intentions and we are hacking we want to find open ports in networks of other people now notice that port scanning is illegal even though it's not a hacking attack in and of itself it's an illegal act so don't scan networks that you don't have any permission for only scan your own network your own computers your own servers don't do this for exploitation purposes so i've warned you i don't take any responsibility for what you're doing this content here is purely educational so if you use it for something bad it's your fault and i do not advise it now let's get into port scanning itself how does port scanning work or how are we going to scan ports now what we're going to do is we're going to use sockets um to connect to a certain target to to connect to a certain server or ip address at a specific port if the connection succeeds we're going to say this port is open if it does not succeed we're going to say disport is closed and to do that we're going to implement a port scan method so let's start with that we're going to import the socket module and we're going to say uh def port scan and we're going to pass a port here now to scan a port as we said we have to try to connect so what we're going to do is we're going to create a socket first uh socket dot socket um socket again dot af e-net or inet which stands for internet basically we're just saying okay this socket is an internet socket and not a unix socket and the second parameter is socket dot sock stream sorry sock stream which basically just says that we are using tcp instead of udp now that we have created a socket what we're going to do is we're going to connect um and before we can connect we have to define where we're going to connect to because when we use the connect method we have to pass a tuple and the first part of the tuple is the ip address which would be our target and the second one the second parameter here is the port so the port is actually the parameter of this function so we can just pass it but the target we have to define a target and as i said use your own computers use your own servers or servers that you are permitted to use so uh do whatever you want but don't scan the network or someone else that you don't have permission to so basically just pick a device from your home now in my case i'm going to pick my router which has the ip address 10.0.0.138 and it's my default gateway if you don't know what ip address to choose you can always pick localhost localhost would be 127.0.0.1 this would be your own machine that you're operating on right now so if you don't know what to scan just scan your own computer that you're working on right now now what we're doing here is we're saying connect to the target which is our ip address here and we're saying connect on this particular port now if we don't get any errors or any exceptions up until now the connection succeeded and we can return true this means our port scan was successful or basically the port scan was always successful but our port is open so we found an open port the connection was successful if this is not the case so if we get some exception some error we're going to just return false now with this method here already we can scan ports so i can just say print port scan 80 should be open because it's http and as you can see i get true now if i check for another port maybe 98 hopefully it's closed yeah it's close so i get false um so whenever i get i cannot connect to a port i return false and every time i can connect to a port i return true so this is how this method works and we could go ahead now and just write a for loop for port in range and then just define a range of ports for example from 1 to 124 which would actually just scan up until 123. these are the so-called standardized ports that are reserved for http ftp uh and ssh telnet and so on so we're going to say scan all of these ports and every time i get a result which is either true and false so board scan port so we're scanning the port that we have right now in the loop and then we say if the result we can just say if results since it's a boolean so if true if false you know if the result is true we say print port whatever is open and we can format in the port number and otherwise we just print port whatever is closed format port so when we run this you will see that it starts checking for all the ports like port 1 is closed port 2 is closed and so on and it continues to do that in a very very slow pace as you can see we barely make any progress it's very very slow now to change that what we can do is we can introduce multi-threading as i said and to do this we cannot just start 30 threads because it would be very inefficient to just run multiple threads because if we just run multiple threads what happens is we can or the possibility is there that we check the same port number twice so to make this as efficient as possible we're going to use so called cues so we're going to import two more libraries here first of all import threading because we need we need the threats and also from q import q with a capital q so a cube basically is like a connect a collection or like a sequence like a list maybe where we have all kinds of elements and every time that we get an element from this list it's no longer in the list so uh we're basically cueing the elements in this case we're queuing the port numbers and i can say i have all the ports numbers uh port numbers from one to one thousand and every time i get one uh the whole list the whole sequence shifts and i can get a new one well we'll see how this works in a second but first of all let's remove this loop and start by defining an empty queue here that we're going to fill up later on so q equals q and i'm also going to create an empty list with the o for the open ports actually this is the list where at the end we'll add all the open ports so that we can see which ports are open in an uh final report now what we're going to do now is we're going to fill up this queue and to do this you can choose whatever method you want you can just fill uh i don't know 10 000 porch numbers into it you can uh fill just a list of numbers into it you can write your own method if you want what we're going to do right now is we're going to define a method fill fill queue and we're going to uh say from port and to port so we're going to define a range you can also pass a list it doesn't matter basically you're just saying or let's let's do a list actually it's i think it's more it's better let's say port list we're going to pass a port list and what we're going to do is very simple we're just saying 4 port in port list we are going to put in every port into the queue now the queue operates by the first in first out system so the port that enters the list first is the first to get scanned so i'll start putting in one two three and these are the ports that will be scanned first so i'm basically just taking the list that we can pass later on and i'm filling this list into the queue now the next step is to define a so-called worker method because the worker method is the actual function or method which our threads are going to be using so when we run a thread we want it to execute this function and this will be the port scan actually so we're going to save for every thread every thread is going to execute this while not q dot empty so basically as long as there are elements that are not scanned in the queue as long as the queue is not empty what i'm going to do is i'm going to say port equals q dot get so i'm going to get the next port in the list since it's not empty i'm going to get one and then i'm going to say if port scan of this port returns true i'm going to print port whatever is open and we're going to say format port and additionally we're going to add the port to the open ports list so we're going to say open ports dot append port so we're adding our port to the open ports list so that we can have a good final report in the end now otherwise if you want you can also print port whatever is closed but when we run that many threads it will be very very hard to find the open ports because we'll have a lot of statements at the same time so i think it's more beneficial to just print the open port just so we get a better overview of this so we're going to delete this and we're only going to print something if the port scan returns true otherwise we're not going to do anything so these are the functions that we're going to use now what we need to do is first of all we need to fill our queue and we can do whatever we want you can say i want all the ports from 0 to 5 000 or i want only 22 80 443 and so on only the important ports that i'm interested in just to find your own list if you want i'm going to say a port list equals range 1 up until 124 and now i'm going to say fill queue port list so the next step is to define a an empty thread list and i'm going to explain in a second why we need a list for our threads because actually to run the threads we don't need this list but we're going to need this list later on because otherwise the last part of this script is not going to work so first of all we're going to say 40 in range and now we're going to specify the number of threads that we go uh we want to run so do you want to run 10 threads do you want to run 20 threads 100 threads whatever so let's start with 10 threads so range 10 and now we're going to say threat equals threading dot thread with a capital t and we're going to say target equals target equals worker notice that we're not calling the worker function here so we're not saying worker in parentheses we're just saying worker so we're referring to the worker function without actually calling it now what we're doing here is we're creating 10 so range 10. so 10 times we're creating a new thread with the worker as the target function and then what i'm going to do is i'm going to say thread threadless dot append thread and then we have all these threads that we created right now in our list now the next step is to run all of these so we can save for thread in thread list thread dot start and last but not least this is the important part why we need the list we're going to wait for all threads to finish so we're going to say for thread in thread list thread dot join the join method waits until the thread is done until it continues with the code so after this statement here we're going to print the open ports open ports are and open ports and the reason we have to join here is because we don't want this to get printed until all the threads are done so we only want to print all the ports that are open in the end when every thread is finished so basically that's it now let's run this when we run this you will see that we're going to make progress quite fast so we already reached 22.25 and it scan basically scans 10 ports per second more or less we have 10 times the speed that we had in the beginning so as you can see we already reached port 80 but it's still not the fastest so if we want to have this even faster we just don't say 10 but we can say a hundred and then it will already scan 100 ports so we already scan port 80 143 and so on and it's way faster and we can't keep increasing the number as long as it seems to be faster because you know sometimes or at some point you you will reach a limit and your computer is not going to execute faster but you can try with 500 for example and you will immediately reach 500 as you can see so it's quite fast i think when you say a million it's not uh it will not be faster but as you can see with 500 it works quite well these are the open ports actually quite a few and i'm going to have to take care of that because obviously a lot of ports are open in my router we're going to develop a tcp chat in python so we're going to set up a server and we're going to set up multiple clients and these clients can then connect to the server which works as a chat room you could say and each client can then send messages to the server with his or her nickname and all the other clients can see these messages and respond so let us get into the code now the first thing we're going to do is we're going to create a server file so we're going to right click onto the directory and create a server.py file and in here we're going to import threading import threading and import sockets these are the two modules that we're going to need in this video and if you don't know how to work with sockets or you don't know what sockets are you don't know what multi-threading is i highly recommend that you check out the python intermediate tutorial series on this channel because there i talk about network programming about multi-threading what these things are i also have a tutorial on how to make a port scanner a multi-threaded port scanner where i use both concepts so check out these videos uh because i'm not going to go too much into the details of threading or sockets in this video now the first thing we need to do here is we need to define a host address and a port for our server so the host in this case will be just uh 127.0.0.1 because we're using localhost so let's add a comment here localhost this is just because we are running this on our machine if you run the server on a web server you should always uh pick the host address of the server so always the ip address of the server uh this is just the basic localhost since we're running it on this computer it uh will be localhost then we need a port and as a port you can choose whatever you want you could just go with 99872 or something like that what you shouldn't do is you shouldn't take ports like 80 because this is http you should just not pick any reserve ports or well-known ports at all so uh just don't choose any ports from one to i don't know i think 10 000 or something but we're just going to go with 55 555. this is a solid port um and then what we need to do is we need to start service so we're going to say server equals socket and in here we're going to say it's an internet socket so socket dot af inet and then we're going to say it's uh socket.stream so again if you don't know what that means uh oh sorry socket dot suck stream if you don't know what that is and if you don't know uh why we're creating a socket in that way check out the intermediate tutorial series they will talk about these concepts so next thing is we need to bind the server to the host and the ip address so we say server.bind and we pass a tuple of host and port so we're saying okay the server is bound to the localhost on port five five five five five five i think this was five times fives hopefully uh then we say server.listen which basically puts our server into listening mode for a new connection so as soon as we say server.listen the server starts listening for incoming connections now what we're going to do next is we're going to define a couple of methods we're going to define three methods the first one being a broadcast method the second one being a handle method for client connections and the last one being a receive method which basically combines all the methods into a main method you could say but before we do that we're going to define two empty lists here and these two empty lists are the clients list and the nicknames list so these two lists will be the list where we put all of our clients in so if we have a new client connecting to the server we're going to put it into the clients list and also we're going to get the nickname of this client which the client can then later on choose and we're going to say okay the client x has the nickname uh i don't know bob or something like that and then we can just use clients and nicknames to do certain things later on now the first function we're going to define here is the broadcast function is a very simple function it's just a function that sends a message to all the clients that are currently connected to this server so i'm going to say def broadcast and we're going to pass a message here so we're going to say broadcast message and then we're just going to save for every client in the clients list which now is empty but later on we're going to fill it up for every client that is now connected to the server we're just going to say dot sent this message very simple we're just getting all the clients and sending a particular message and this is how you broadcast messages from a server to all the clients so the next thing that we want to do is we want to handle the client connection so when a client connects to the server we want to receive messages from the client if the client is sending any and then we also want to uh send back messages to all the other clients depending on what the client sends so if client a says hi we want to get this message process it and then broadcast it to all the other clients including uh also client a itself because every client needs to see what's happening in the server so what we want to do is want to find a handle function and we want to handle one particular client so we're we're going to later on run this function on all of the individual clients but for now we're just handling one uh single client so we're getting the client and what we do is we say while true basically we're starting an endless loop here we're saying try a certain thing so as long as it works without giving you an exception or an error we're going to just say message equals client.receive i think it's like that our ecv uh 1024 bytes just the basic method uh message so what we do here is we say okay as long as it works that we receive a message from the client we're just going to broadcast it to all the other uh clients or oh sorry no uh broadcast a message to all the other clients so what we're doing here is we say try to receive a message from the client and if that succeeds broadcast this message to all the other clients including this client as well if that doesn't work so if we get some exception some error while receiving the message or while broadcasting what we're going to do is we're going to just uh cut the connection to this particular client remove it from the list and then uh basically terminate this function so we're going to say or terminate this loop so we're going to say the index of this particular client is the clients.index of this client and we need this index in order to remove the nickname and the client from the list so we're just getting the index okay where is this particular client that failed right now in the list which index does it have and then we're going to say clients.remove client so we're going to just remove the client we're going to close the connection to the client and then we're also going to say okay the nickname of this client is the nicknames index of the client so basically whenever we're adding a client we're also adding the nickname so they will always have the same index and when we remove a client we also remove the nickname on this particular index so that we don't get any inconsistencies here so what we do then is we say nicknames dot remove our nickname and you could either print it before that i'm going to print it before that or you can print it afterwards we're just going to broadcast to all the clients that this client has now left so we're going to say broadcast and we're going to use an f string here and we're going to say nickname left the chat for example um and then we're going to encode this message in ascii code so that we get the right message so after that of course we're breaking out of the loop and that's it so we're handling a client one client connects and what we're doing is we're constantly trying to get messages from this client uh this will not give you an error if the client is not sending anything but it will give you an error if this client is not there anymore so as soon as a client produces some kind of error what we do is we just remove it from the list remove the nickname and broadcast to all the different uh clients connected to the server that this client is now left and then we just terminate this function so this function will later on run in a thread for each client we'll have a single thread running and processing this particular function or actually executing the handle function and as soon as a client disconnects what we do is we just break this loop and therefore terminate the function therefore terminate or end the threat so this is how we're going to handle the client connection so now last but not least in the server what we're going to do is we're going to define the main method the receive method which combines all these things that we've written up until now into one function so we're going to say def receive and we're going to just receive client connection so we're saying while true what the server is doing it is basically accepting all the connections so we're going to say client and address equals server.accept so what's happening is we're running the accept method all the time and if this method gets a connection what we get what it returns is a client and the address of the client so in this case we're always going to have the same address since we're on one computer but if you have this running on a server you'll see the address the ip address of this client connecting to your server so basically we're connecting to clients or allowing the clients to connect and if this is done if this happens if a client connects we're just going to say print on the server itself this is not a broadcast this is just on the server console so that we see what's happening um connected with and let's make an f string out of this connected with address so that we know actually we should say str address double d there you go so we're waiting for a connection we're accepting all the connections coming and if a connection happens to come in fact come in this moment what we do is we just print that we now connect it to this client on this particular address and then of course what we want to do is we want to get the nickname of the client so the client will be able before it connects to our server to choose a nickname and it will then it will then be the nickname that is displayed on the server uh so what we need to do first is we need to ask the client for the nickname because of course if it just sends us a message we're going to process it but the first message that the client sends to us should be the nickname so what we're going to say is we're going to send a message to this client and this message will be a code word which is not visible to the user of the client it's just visible to the client itself later on in the code we're going to send the keyword nick and if the client receives this keyword nick it should be um it should be informed that it should send the nickname to the server so that the server knows who are you we're going to say encode ascii again and we're basically just sending this keyword and in the next step what we hope to receive from the client is the nickname itself so we're going to say client dot receive and we're going to receive 1024 bytes and decode them from ascii so then of course what we're going to do is we're going to say nicknames dot append nickname and clients dot append client and then what we need to do is we just need to send a couple of messages here so we're going to say okay print nickname of the client is okay so there you go nickname of the client is and then nickname of the k9 of the client just connected is whatever and then we're just going to broadcast that so that everyone every client is currently connected to the server knows that this client is now connected and that's the nickname of this client so we're just going to say f string nickname joined the chat and we're going to encode this message again and then every server sorry every client knows that there is a new client in this chat and they get a message that this client just joined the chat with the respective nickname and then we're going to send the particular client that just connected we're going to send to the one client that uh this client connected to the server so we're going to say sent uh connect it to the server so that the client knows that it's now connected and it can start chatting and of course we're going to encode this message as well now we're almost done the last two things that we're going to do is we're going to define a thread and run a thread so we're going to say threat as we said we're going to run one thread for each client connected because we need to handle them at the same time we cannot just handle them serially because uh one client might send something and another client might send something and we need to process it at the same time or at least uh roughly at the same time and not just you know process one client interaction then start with the next one so what we're going to do is we're going to say threading dot threat capital t and the target of this thread will be the handle function and the arguments will be just client and then we're going to say thread dot start and if you know about if you know how to deal with python threads you know that you need to use the start method and not to run method because otherwise this doesn't work so let's uh look one more time at this code what we're doing is we're just saying accept clients all the time when a client actually connects we're going to just say okay connected with this client so that the server admin knows what's happening then we're going to send to the client the keyword nick or the code word nick so that the client knows okay i need to send my nickname we're then going to receive the nickname from the client append this nickname and this client to our lists and then we're going to print on the server again for the server admin that the nickname of this client is whatever then we're going to broadcast to all the clients connected to the server that this client with this nickname now join the chat we're going to send a message to the particular client that the connection was successful and then we're going to start a thread handling the connection to this particular client so now we can actually start coding the client but before we do that i need to add one more line here the receive method also needs to be called because we defined all this but we didn't run it so the received method is our main method and it runs down here uh we could actually also go ahead and run the server but you're not going to see anything but a good sign is that it's running and not crashing so it probably works but for the server to do something of course we need a client to connect to it because otherwise it's not going to do anything what we could do is we could just print out the message server is listening listen dot dot dot and then it yeah you can see the server is listening and that's how you run the server now the next thing is we need to define the client so we're going to say client dot py and here also we're going to import socket and import threading and we're also going to define a socket so we're going to say client equals socket dot socket af oh sorry socket dot af by net and socket dot sock stream there you go and now instead of binding the client to our a port and a host we're going to connect it to a host on the port so we're going to say client.connect and we're going to connect it to localhost so 127.0.0.1 and we're going to connect it on port 5555 and now we're connecting it to the server so in this line when this line gets executed the server will receive uh will trigger the accept method and the client is now connected to the server so what we're going to do in this client is we're going to define two methods and run two threads simultaneously so we're going to receive all the time data from the server so we're going to have a receive function that's running constantly and at the same time we're going to um to send messages or we need a thread running for all the messages that we're going to send so let's start with the receiving part define a function receive and this function is just running again in a while true loop and we're going to try something all the time what we're going to try is we're going to receive messages from the server so in this case uh we'll say client.receive but the client is actually receiving from the server so what we're going to do is we're going to say message equals client.receive just don't get confused we're still receiving from the server not from the client but uh for the server to send messages it uses a client so it could be considered a client so we're receiving 1024 bytes and we're decoding what we receive and that's basically it now what we need to do is we need to check if the message that we just received is nick or something else so we're going to say okay if message equals nick which is the key word for sending the nickname we're going to send the nickname i'm just going to pass here because we need to get the nickname first in the beginning of the script and if it's not nickname what we're going to do is we're just going to print the message so whenever we get a message from the server that's not nik or any other keyword that we define we're just going to print the message because we're not going to do anything about it we just want to see what the server has to tell us so we're going to say message print or print message if that doesn't work what we're going to do is we're just going to close the connection so we're going to say uh an error occurred and i think double r i'm not sure oh man i think it's misspelt yeah double r uh an error occurred and uh then we're just going to close the connection so we're going to say client close and we're going to break this endless loop now how are we going to send the nickname first of all we need the nickname so we're going to say nickname equals input choose a nickname so whenever we run a client the first thing that we want to do is we want to choose a nickname and if the message equals nick what we're going to do is we're going to say client dot send and we're going to send the nickname the encoded version to the server so what's happening here is the server is listening all the time the client is choosing a nickname connects to the server and the moment this happens this gets triggered we say connected with whomever and the first thing that the server then does is it sends the keyword nic so we're going to get the keyword nick we're going to send the client name or the nickname then we're going to receive it here append it and whatever and then we're having a connection and as soon as the server sends something to us we're going to receive it and print it onto our screen now let's finish off the client by defining the second function which is the write function and what this function does is it runs a while loop as well in endless loop and here what we do is we always define a new message so we're going to say message equals um f string and here we're going to say nickname colon and then the actual message the actual message is always what the user puts into the script so oh i need to use double quotation marks here um what we're doing here is we're constantly running new input functions so as soon as the user clicks enter and sends one input we ask for the next one so the user the only option that the user has is to either close the client or write new messages so we are always waiting for new messages this is a threat receive and write will run simultaneously and the right function is always waiting for a new message and you send a message by clicking the enter key and once you get a message so once you click enter or press enter what happens is you say client dot sent and we're sending the message of course encoded and that's basically it that's the whole function and now what we need to do is we need to run two threads we need to run a receipt thread and a right thread so we're going to say receive thread equals threading dot thread with the target function of receive we don't need any arguments here and then we're going to say receive thread dot start and then we're going to do the same thing for the writing thread so right thread equals threading dot threat and a target here is the write function and we're going to start this thread as well and now we're done with that but uh the problem here is that in pycharm we can only run one client at a time and to see how this works we need to run one server and two clients so i'm going to run this in a command line right now so right here i navigated three terminals into the direction of the tcp chat and what i'm going to do on the left side here this will be a server and these two right terminals here are going to be um the clients so i'm going to just say python server dot py and as you can see server is listening and here we're just going to say python client and we can choose a nickname so for example let's say neural nine is a nickname and as you can see we get connected with the ip address and the port nickname of the client is neural nine i can see here on the right neural nine jointer chat because this is a broadcast message that gets sent to all the clients including myself and also connected to the server and now we can run a second client so we say python client.py and i can choose a nickname here let's say youtube audience so you guys and you can see i get here again connected nickname is youtube audience here i see youtube audience joined to chat connected to server and here on neural nine i can see uh youtube audience joined the chat so i can say hi or hey youtube then what happens here in the server i don't see anything because the server is just monitoring the connections and here on the client side i see hey youtube from myself but also the youtube audience here sees hey youtube from neural nine so it can answer hey what's up and i can also see it up here and i can also start spamming here if i want and you'll see it in both uh clients so this is how you do a professional advanced chat of course you could also add some special commands like kik or ban or i don't know emojis or something but this is a basic version of a chat room
Info
Channel: freeCodeCamp.org
Views: 182,839
Rating: 4.9599047 out of 5
Keywords: python networking, port scanner, mailing client, chat room, DDOS
Id: FGdiSJakIS4
Channel Id: undefined
Length: 68min 35sec (4115 seconds)
Published: Fri Aug 07 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.