TCP Client Server Application | C++ in 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys welcome to c plus plus in 2021. so as the title implies today we are going to look into socket networking uh and making a basic tcp uh client server application we're not going to get too deep into it today we're going to build the scaffolding out and then we will expand upon it next time because this is something that will be ongoing as i was looking for a larger project to base our c plus plus uh lessons around and this will be a a good example because we can branch off into doing stuff like http connections and uh we can expand our threading to instead of being a single thread we can do thread pools with this and there's a lot of things we can do building out a server servers are can be pretty chunky applications so we can really put as much work or as little work as we want into we're going to be switching from visual studio c plus plus to c make base project i'm personally going to use c line but you can use any any other c make based application if you don't know how to do that check my game mention series above i believe i show how to do it in visual studio code but you can do it as i show you today in sea lion that being said let's just jump into it and hopefully we have a good time doing it hit the like button all right so let's just jump in and start building out our applications so as i said we are going to do this in c-line but you can use any compatible cmake editor that you would like so i'm going to click new project i'm going to make an executable for now with the c plus 20 standard and we're going to call our project mud on your face and that's going to be the name of our game and you'll see that we've got a very basic program with this main list here now the main issue that we're going to have here is that we do not want to have the the server and the client be the same application but we want to be able to work with them within the same project so um what we're going to do is we're actually going to move these main.cpp out into their own folders so we're going to hit new folder here new directory and we're going to call call this uh mud on your face and wife server and we're gonna make another function new uh directory my client client and then we will actually move this cmake list into my client here i will do that and here we're going to change this to moife client and we will copy these actually and we are going to paste them in the moist server i'll make this my server like this and here we're actually just going to change it to project name so that we don't need to worry about uh renaming it and we'll do the same thing here all right so we have two uh applications here my client and moist server now this is not going to load properly notice how there's no configurations up top because we need a um a parent cmake list so we're going to right click here and we're going to new and we'll say cmakelist.txt and we're going to go here we're going to copy this project here we're going to project my client and what we're what we're going to do we're just going to add subdirectory moif client and we're going to add subdirectory moife server web server and if we reload those changes uh no c make minimum version required so uh this doesn't show up here right oh yes it does so we will add this here as well and we will reload these changes and finish now you'll notice here now we have both of our client and server here and if we want to run them let's just say hello this is the server hello server and this is the client so we'll say hello client and if we play that you'll see it build it links hello client and if we go to the server we got hello server so we've got our two applications now we want a library to share between them uh what we're going to do here is we're actually going to make a another folder and we're going to call this morph networking and in here there's going to be one more cmake list and let's just copy this as a base and what we need to do is we want to say add library project name here and we are going to add the subdirectory up here moist networking because another target right if you go here we want to change this to moist networking as well networking there we go and now if we build all of this oh there's no main.cpp that's fine so can we build this now no sources that's fine well we can deal with that in a second so what we want to do is our library want the same structure as we had before we want a source directory and we want an include directory and include here we're going to call it mike networking and then just to be um as to have an example we are going to create a header file here we'll say mybase.h and we're going to create a new source file here and we'll call this myth base.cpp and this is going to include moife networking slash base dot h and actually we're going to rename this to um we're just going to call it bass dot h and we're going to call this one bass.cpp okay so this will still tell us there's no sources so let's fix that so we've created our library structure like this and what we want to be doing is being able to use our base.h file within our client and server so what we need to do is what we'll do is we'll quickly make an enum class and call it um my email and we'll just say one two and three now we want to be able to use this enum inside here so i've already included the base in this file so let's just say void yeah let's just do this and we'll just hopefully we'll we'll be able to include this networking file inside our project now to be able to include this networking file what we'll do is we're going to target link target include directories is what we want and we'll do it by project name and we are going to create a public section public section here and what we're going to do is we're going to go to our youtube game engine and we're actually just going to copy what we had in our engine library here which is our installer interface include and our build interface includes and we'll add those to here and let's do this we'll reload this now if we go inside here you'll see that now it works so in our top cmake list notice how we include we added more networking first and then we added the second ones i believe that's important um because these two are going to rely on this this top one so in our client what we're going to do is we are going to say uh we want to be able to include muay networking base.h right that's our goal now it's going to show red squiggle all we need to do for that is first we're going to say target include directories project name again public and we are going to just add more networking here and we also need to add target link libraries and again project name public wife networking here now that should be enough let's reload this you shouldn't get any errors from cmake when it reloads that and when you rebuild your client you'll see it builds and if we go inside here this include turned gray and what we can just say here is we can say cast this to static cast cast integer thing uh my enum 1 right now we can do the same thing for our server so we can take we can basically just copy this and put it inside our server like this and we don't want to add these and let's fix the indentation here exit here and reload those changes and we can do basically the same thing inside our main.cpp and just do that and we are going to do enum 2 just to be thorough so if we hit play on that you'll see if print zero which is enum1 and if we go to our server and play our server we get one so with our basic project set up our next step is going to be to include the libraries we're going to use into our application which is going to be uh the boost library so if you look um if you go to boost.org you'll see right at the front page of the current release button with version one seven seven zero click that button and download it i've already done it then once you have it downloaded you'll want to extract it somewhere i personally put in my source directory here under libraries i have boost 1770 here so in order for cmake to find our boost library we're going to need to define some environment variables for cmake to look up in order to find boost so i'll show you how to do it on both linux and windows on mac is just a tiny bit different so on linux if you go to ubuntu i have an ubuntu box here you're going to want to set it inside your um bash rc so you'll want to do like nano which is a text editor uh your home directory dot rc you'll get a file like this you go to the bottom and you do something like export [Music] export [Music] boost root equal and then path two boost and then one seven seven zero like that and that's how you would uh do it you would then save your file which is ctrl x and then y and then enter and then you would need to relaunch your your editor so relaunch clion close down and open it up on windows we've done this before you you can hit the windows key to open this just type in environment variables you'll get edit the system environment variables uh click the environment variables button and i've already done it but here you would click new you click new variable name and which would be boost root and then variable value you browse directory and find your boost directory which is what i've done here and again if you set that up and it wasn't already set up you'll need to shut down c-line and restart it which i don't need to do because i already had it set up now with your environment variable set uh all we need to do is uh find the package and add it to our our library so what we will do is here let's not have that we'll say find find package we'll say boost and then we put in the version which is 1.77.0 which is our and then we put required so with that done we're just going to add them to our project so we're going to add a private field here and we are going to put the environment variable boost underscore includers and then we need to create a target link libraries uh which is also going to be project name and let's see project name and then this will be again we'll put private because we don't have anything public right now and this will be boost libraries like this and that should work so let's reload those changes and everything built okay now if we go to our base.tpp um we got our enum let's make a function right uh just to test out our integration so we're going to use the example that was given that's given to you on the getting started docs from boost.org uh which i'm just going to paste in here just to double to check everything so the first thing we're going to bring in some stuff so we'll bring in these files here and then we are going to create a function function uh void multiply by 3 and we are going to just do this here now this is very not a thing to put inside the library because it blocks and all sorts of stuff but we can do that and then we should be able to build if that doesn't work we can figure out so this doesn't work cannot include lambda because now this is normal because notice here how our public interface has these but boost is private right so what we want to do is we want to make this an interface uh let's just copy this we'll make this an interface here we'll delete this we will move it to base.cpp and we will actually just move all these includes into base.cpp as well now that should be much better now that we should be able to build good now uh let's do it in our server uh we're including base.h so we can call multiply by three and what this will do is it will wait for a number and then it will just print out that number multiplied by three but um let's let's just put a new line in here right so let's uh hit play on that it's gonna build our server so it's waiting for an input we take three it prints nine take put four prints twelve print nineteen prints fifty seven and that's exactly what we wanna do and then we can uh quit that by hitting the stop button okay so with our boost libraries in place let's start building our client and our server now our server itself it's going to start fairly simple what we want to do first what we're going to do actually is we're going to make these boost includes public just so we can start building stuff out and we'll start abstracting things out as we can and hopefully we won't have any boost things left in our main server places so with that in the public we should be able to include um our boost as seo here so include boost seo hpp right um and let's let's clear out our library for now let's clear out our library because we don't want to have this for now i'll close that and remove this and move that that's fine we can kind of no base no include all right so uh we've got our mo we got our boostasia right so the first thing we're going to do is we need to open a input output or an io context a boost io context so we're going to wrap it in a try block for exception handling which we're actually going to look into in a future lesson where i'm going to go into more detail on exception handling but we're going to wrap it in a try block we're going to call boost uh seo io context and we're going to call it io context because why not then we need to create an acceptor object that will listen for connection to incoming connections so we will say tcp um right so if we we we need the tcp object but it's under uh boost seo uh iptcp right so what we're going to do to make it a little bit easier on ourselves we're at the top of this file we're going to put it using here and we'll call it using oops using here and we'll call it tcp uh we don't even need the tcp we can just do that and then from here we can say tcp acceptor and then we call it acceptor and io give it the context we created and then we give it our endpoint let me give it to we give it a v4 endpoint and we give it the i believe it's the port number yeah if i recall correctly with that uh we created our acceptor and we want to go into an infinite loop so we can do either four like this but i personally like while true and then we'll do tcp socket because we want to create a socket socket and we again give it the item we again give it the i o context then we accept a connection on that socket acceptor dot accept on that socket now what that will do is that it'll wait it i believe it blocks here until it gets into the connection and once it gets the connection here it will put the information inside that socket so then we want to send a message back to the client that connects so we'll make a stud string and we are going to say hello message and we'll say a hello beautiful beautiful client and we'll just give it that and then we are going to give it a we have to give it an error return so if we give it boost system error code error we can say boost oops boost seo right right on the socket and we give it a boost acio buffer of the message which is the message and we give it the error that we want it to populate then we want to catch an exception so let's say catch stood exception and e and then inside here we will just put it out to here now this should work now why is it giving me red squiggles right that's where i want to put it i just put the cats at the wrong spot yeah so let's include include iostream and build that now i don't know why i'm missing so many squiggles okay reloading the cma project force everything to update itself all right so that is a our basic server right there now all this is doing um going over this again yeah it's making an i o context which is just a context object that boosts uses to keep information on your input output for your system i imagine you're creating an acceptor to accept connections and then with your acceptor you're waiting for a connection and storing that connection in the socket and then once you have the connection you are writing to that socket and then when this goes out of scope when it goes back around socket falls out of scope so we'll actually close the socket in i believe in the socket destructor it automatically closes so let if we look at that um let's just say here we'll put a stud accepting connections right and we'll put a new line of having trouble typing today put a new line there and here and we'll say on port 1337 now this is this is the port number that we want to give here there we go so this will accept connections on port 1337 and using i o context now i don't know how v6 would work but we'll look into that again further so if we play this you're going to notice it doesn't really do much it's going to say accepting connections and that's just going to block there we'll allow access and it just blocks on accepting connections on port one three three seven now with that out of the way we're going to just start our server here and it's running um actually what we will do we'll make one more change to it we'll say um here stood cow client connected sending message just so we can see everything that's happening right so let's build this and anyways so we've got a server running now let's build our client which will just uh receive this message and and close so we're in our main.cpp here now what we want to do for our client is going to be a little bit uh similar but um different so first things first uh we are going to also want our booth booth slash seo.hbp and what are we going to do the first thing we're going to do is we're going to expand this to get arguments um no we're going to skip the arguments for now but we'll just we'll put this in here just because i want it for later arg b like this now let's take this and i also put inside our server just because just for just for posterity now similar stuff we'll hit try here and we'll put our catch here good exception e okay okay so we have our try catch block now inside here we'll switch this to client just so we don't do it by accident now um what we want is we want to again create our i o context boost seo i o context io context now we're going to do this a little bit more my style now we're going to create a tcp resolver which is kind of like the the equivalent of the tcp acceptor except for it makes connections right so resolver resolver and we are going to give it the i o context now we're going to do this start doing this in a lot more modern way so we'll do it like that now the resolver it takes a hostname um why is all right we want to also using boost seo tcp or ip tcp like that now we want to get a list of endpoints for our resolver to connect to so what we want to do is the first thing we're going to do is we're going to say tcp resolver results type which is what it's going to return endpoints equal resolver dot resolve now here we're going to give it the ip that we want to connect to so in our case we're going to do localhost and then the port or the service that we want to connect to now we gave it 1 337 like this and here actually what we're going to do is we're going to change this to auto because um yeah why not so with our endpoints created we want to create a socket so tcp socket i o context and then with our socket we want to connect so boost acio connect socket endpoints so i misspoke earlier the resolver is to resolve the possible endpoints for this apparently so uh what we will do now is we will uh just listen for messages um and this is not working why does that not work oh uh i owe context first here oops that's what i did wrong socket endpoints and then we can do that so i just forgot to name it um name in my socket here all right so with that out of the way uh we have connected to our socket and we will listen for messages so we will hit while true so first we define a buffer now the example is using boost array but i want i would prefer to just use the standard array if possible so we will say include standard wet array and we'll say just did array character of 128 and we'll call it buffer right then we will say boost system error code error and if we do size t length equal read thumb over boost action buffer buffer there now if error is equal to boost seo error end of file that means that we have successfully um we've received a clean shutdown so basically the do that um if we receive end of file from boost from our socket that means that the server has cleanly cut the connection so we just break here and we'll just put a clean connection cut off and then otherwise we will throw a boost system system error there and finally we will stood out and we will include iostream with that then again we will do the same thing we did inside here with our error i don't feel like typing it again we will do this here now this is telling me it's unreachable which is not uh all right else if error so if the error is not nothing then we will build it so let's build our client now and in theory it should uh print off our hello hello whatever hello beautiful client so if you look here what we're doing again we create the i o constants we create a resolver to resolve the host to create a connection string basically or a series of connection strings then we create the socket and we connect to the socket if the connection to the socket is successful i believe this will throw an error if it doesn't connect but anyways if it doesn't if it succeeds it will listen for it will listen for for messages and print them to the console otherwise if there's an error it will will quit and that's all we need so let's watch our client and see what happens and hello beautiful client and if we look at our server client connected and then it starts accepting connections again now if we change this to a different port what happens if it can't connect it will no connection could be made because the target machine actively refused it and that makes sense now if we take this and it just doesn't there is just no machine it should give a different error yeah basically basically no connection could be made so it uh went to e.1. i imagine that this is where it's going let's just double oops to stop this turn this off here now i imagine that this is where it's going yeah and it goes straight to the catch block here and that's that's where the the um see that's where that gets printed right so now let's make this a little bit more um interesting what we're going to do is you'll notice here that this is all inline synchronous we're going to make a asynchronous client using a boost library so we're going to actually do this inside our library itself and then we're going to move stuff over so the the client's going to stay the same for now it's just going to listen for messages and we'll probably move this out later but for the in the case of our server that's where we're going to make it the biggest change so the first thing we're going to do is we're going to say new um c plus class and we'll just say server first we're going to create a settings file we're going to create this to snake case like i like it and we're going to say server it's going to be a server class all right we have a server class with server.cpp we're going to move this oops i'll do this right factor that uh we're going to delete our base files now i believe it's adding stuff into one of these cmake files oh maybe not yeah it added it to here which i don't want because we're globbing stuff okay and we'll reload those changes all right so we've got our server class we're going to wrap it in a namespace and we're going to call it moife so the first thing we're going to do is we're actually going to rename this we're going to say tcp server we can name this uh this forgot renamed automatically and we're gonna rename this tcp server as well uh and we're gonna rename it one more time and tcp will be all cut all caps because that's what i want i will make our public and private sections for now so what we want to do is we want to have a tcp server constructor and what this is going to take it's going to take a we're going to want a port and we're going to also want the tcp version so we are also going to say um we're going to create our own enum class here and we're going to say it's going to be the ipv version uh not class enum it's gonna be enum class and it's going to say uh b4 and b6 now we could use our so we could use base boost um constants for this like we did before if you look here we passed in tcp v4 here but the idea here is that this way we can abstract it out and possibly switch out our networking backend in the future if we see fit so the first thing we are going to want to do is our tcp ver ip version so it's going to take ipv ip version and it's also going to take a const uh no we'll just say a stitch string um port and we'll include that with our what's going on we'll include that and that will be our constructor um let's start with that and we'll work our way through so the tcp server constructor will store do we want to store it or do we want to just um here we actually want to name space morph this do that and then we can get rid of this and i think we can get rid of this too right yeah that'll make it a little bit easier to read um do we want to store it let's just store it um in case we we want it later so uh ip version and then we'll say uh a cd string port and then we can go into our thing here and we can say uh ip version is going to be ipv and then port will be uh right and ports never used but that's fine we can deal with that later now with that done what we can do now is we can actually create our i o context so if we go inside our tcp server we also want to create our boost seo io context do that and we will import this by no we don't want io context we want include boost slash seo dot http that's over that's what we want so we want the i o context and we also want um to create the acceptor which we can do at this point so booth seo acceptor uh no so here what we'll do is again inside this will just be in here using booth seo ip tcp and we'll say all right well you know what we'll fully qualify it seo ip tcp acceptor acceptor now if we go to our server we can now initialize these things as well so our i o context is just going to be a new io context so yeah i'm i'm working on it so acceptor equal booth uh asia ip tcp acceptor io context io context and then [Music] uh which will be uh ip tcp endpoint and then so we're actually just going to use be using that here using because i don't want to have to type this all the time iptcp like this and then we can ipv equal maybe [Music] [Music] okay and port now what this is still complaining about us explicitly does not have a default constructor so i guess i need to do it like this and do it like this i guess now why is this complaining oh this should be an integer so this will actually be an end and port and this will be port is part and tcp server not a string it's an integer and we can we can remove string from here now will that be right and change this to it i know this is kind of insane but there's no default constructor on acceptor so we have to build out the acceptor here now i might be able to just remove this as well yeah because this is basically a constructor here now let's build this right so we've created our tcp server um we might have other stuff to do in there eventually but what we want to do is we want to be able to start accepting yeah so we will also create a function called run which will run our server so we will say void run so okay to void run now what voidrun will do it will actually just run our i o context that's what we want we want to uh i o context dot run and dot run is a uh blocking method so this will block as well so basically until run exits it's always going to work and we will actually say um we'll actually make this return int here let me see top server i'll make this int and we will wrap all of this inside the try catch block exception e and we will copy the same thing here tcp server do this and we're going to return minus one here if there was an error otherwise we will return zero right so that will make our tcp server run and we need a i o stream here include [Music] okay so with that done we have a few things left to do so run will run the context and we will yeah so we will set up a few things inside here so with our acceptor created inside here we are going to set up a few asynchronous things here so um we are going to create a private function here which we will put in a separate section and we are going to say uh start accept now what this will do sorry there's a spider on my monitor that i need to kill uh so this will be a void start accept function and we are going to generate this and what this will do we will call start accept from uh and we will call start except from here now what this is going to do is it's going to it's going to create a connection uh so let's say tcp connection so we want to create a connection and then we want to asynchronously asynchronous we accept the connection right yeah we're gonna need to create the new connection now so um we let's do here uh we're going to say in uc plus plus class tcp connection we're going to name space this one as well then we will uh move this to our source here we will add the namespace here and remove it from our cmake and we will reload these changes so our tcp connection what's it going to do let's add our labels like this uh what's it going to do so the our tcp connection is really just a glorified socket so again we will use the tpc here using uh boosts seo iptcp and include boost cassio.hpp then we will create our socket so tcp socket socket and we are going to create the message that we want to send to the client i when it connects so message equal so stood string message and we'll do this and our message itself will be the same message we had here just so that we have the same thing going on so tcp connection dot h the message itself is going to be the same here there you go and then what do we want to do we want to uh we want to be able to get the socket um of the connection here so we will say uh tcp socket and socket return socket and then what else do we need we will start the connection uh which will write the message so for now we'll just write the message but start and here we'll put socket and um yeah that's fine for the the getter let's move this get her up but void start will be its own function inside here let's go back and right you want to create a tcp connection constructor which is going to be private and we are going to provide a um a create a factory method basically uh specifically because we want to make sure that these are all shared pointers and will fall out of context will fall out of context when they they go out of scope properly uh all right so that's enough for now let's again let's let's generate the definition i don't want to do it in place okay i will make bring this up now i could have done it in place but i like having it things a little bit uh cleaner now the constructor for this will have uh it will mostly just be initializing our socket variable to take our i o contacts here like that and our start method is going to uh basically just write out to that socket so asio async right and now this one takes a socket it takes uh the message that you want to send so in our case it's message and then it will take a binding to a function now uh what i'm going to do is i'm going to i'm hoping that this is going to work that we can just make this a lambda for now and this should be um it's going to take a const boost system error error and it's going to take a size t bytes transfer now message is not defined why is message not defined because i didn't put that there let's do that close system error error code oops error code i do this and this would be a socket like this there we go that worked out all right and then we're going to say stood cow um if error failed to send a message and otherwise else oops do that all right so with that done we are most of the way there let's look at the listed count i need i'll stream okay so last thing we need to provide is a factory method for creating these tcp connections so there might be another thing that we need to well i think i think that's all we need to do so to create our factory message mess method first we're going to define a pointer type so now we want um we want to always reference our connections at the shared pointer so that if they go out of scope they only get destroyed if there's no more references to them so we're going to say using the pointer equal stood shared pointer tcp connection [Music] now with that we probably want to include memory i imagine i think that's where a stood shared pointer is and from there we are going to say uh we're going to provide a static message static uh pointer create [Music] and it's going to take a boost casio io context i have context reference and it's going to return a pointer to new tcp connection like that that should work there we go and now why is this yelling at me there it's implemented good and that is our tcp connection class now what this uh single argument constructor should be marked explicit sure why not um just to shut it up now with that done i think that is everything we need yes we can go back to our tcp server and finish what we were doing so we were inside our async except here so our connection here is actually going to be a tcp connection dot create which should be here [Music] io context like that and this will be we'll just say auto like this right and we can import that and this will give us our shared pointer tcp connection perfect now our acceptor async except now uh the first if you look at what we did with the right if we look at our tcp connection with our right it takes a socket and then it gives it a buffer and then it gives it a callback right so it's going to be similar here it's going to you're going to give it a socket which is going to be our connection socket and then we are going to bind a function that will handle accepting other um other connections so again we are going to pass in this we and this one will take a uh it's going to take a tcp connection pointer and it's going to take the new connection and it's also going to take an error called boost system error code and error and that will look like that now that should be appropriate now what's this complaining about now why is this so i think what i want to do possibly is let's go back so i think the it's going to be boost seo a system error code error like this is that right yes and then we want to capture the connection here and this and then we will say if not error connection [Music] start and then we start accepting a new connection right now i think this is what we want to be doing if we're doing it in a lambda like this right good now in theory this should be basically all we need to run our server let's get rid of the to do i o context so i'm just looking over my notes uh shared from this that's fine uh here inside here this can we do shared from this uh can we do stud share this so we want a so what we want to do is in our tcp connection uh here we are going to say public should enable shared from this right tcp connection like this and then in here we might be able to shared um this will that work okay so what we want to do then is so we want to make this follow our shared pointer so we're going to do auto strong this equal shared from this and we are going to say strong this this and that's all we're going to do and now if we if we want to use any um [Music] we can actually get rid of this um actually we don't want to no we do we'll get rid of this so that if we want to do anything on our object now we want to do it from the shared pointer yeah so you want to do it from the shared pointer so there's no point including this so you this way you explicitly use this strong this right so that's what shared from this does it makes it so that you you can create a shared pointer within yourself uh pointing to your yourself basically and use it within places to ensure that you are reference counting when you're going kind of out of scope and back into scope and stuff right so now let's uh let me look back through i think that's pretty much everything our tcp connection looks is done our tcp server looks done and now we want to look at main so let's look at our main server here now we can get rid of pretty much all of this um here now we're going to extend our server object to be more dynamic in a minute but for now we want to say oops i want to say include include moife and tcp server now we are going to say tcp server server and we want to give it um i believe it's going to be tcp server we want to give it a ipv and a port so oops so we want to say oops let's say moif http server equal ipv v4 and 1337 like that that should create that creates our server like this now we want to just run our server right dot run that should create our that should run our server uh tcp server and run good now that should do it um let's see what that does when we run our server let's hope i didn't make any mistakes along the way because i'm kind of adapting this as i go right so i have nothing here now let's go to our thing and let's look to our client and let's open the client that's so fun uh let's open a terminal and run our client in here because it closed automatically an attempt was made to access stock in a way forbidden by its access permissions uh weird or let's just see what my client is doing oh one three three seven let's build the client and let's try running that again i don't think i would need sudo to connect to a server it seems odd all right let's see hello beautiful client and there we go so that worked out exactly as we wanted it to so if we look here it's this is still running send 25 bytes of data and if we continuously connect to it it will send the 25 bytes of data now so with that you can see our server is doing exactly what we wanted to do but the main issue is that it's not keeping connections open right so in order to keep connections open we have a couple of options that we can do the most obvious one would be to make sure that our connection here um doesn't go out of scope so when when you create it here it's going to reference count to one when it goes into the acceptor async accept it makes a copy here reference counts to two and then immediately exits the start accept function which which reduces the reference count back to one because it this falls out of scope then when this um when async accept is called it will call the this this function which we'll call connection.start which we'll call uh here it will run this which will run run the function and it's creating a shared pointer from this so reference counts to two and then it goes and then it exits the start function then the start function returns to here and it creates another accept but then it immediately falls out of scope which reference counts back to one because tcp connection is still running waiting to finish writing and then once this finishes writing it will reference count to zero and destroy itself so um that's that's the reference counting going on here so in order to keep our connection open without without letting it just fall out of scope and destroy itself the best way to do it is in our tcp server when we create our connection we should create a reference to the connection right so if we go to tcp server we can create a vector here speed vector tcp connection connections and we'll initialize that now we don't have uh the tcp connection in scope here so let's move this to our header file here now what we will do is we'll say connection dot connections connections.pushback connection and then we will actually fix this here this will fix itself now if we build this what we've effectively done now is added one more reference count to it which lives inside this vector um cannot convert to constant right um i did that wrong if i go outside here what we actually want to do is we want to do tcp connection pointer so we want to point her to the tcp connection right so let's build that now this will keep connections open now uh is this still running yeah let's turn this off this will keep connections open until uh this gets cleared so if we run this now oh i'm running client server if we run the server now and then we run the client you'll see that it doesn't actually quit so you'll see it sent to 25 bytes of data but now it's still running right and it's going to run indefinitely because we don't have anything going and that's the beginning of um client all right see and then our client died here um let's let's try this again let's hit server server will be running then we will start our client and if we kill the server like this this is still going but you'll notice here that this connections is probably still there and we can do that over and over again we can connect more clients and we'll continue going but the the connections vector is still going to be active okay so to check if the connection closed we should be able to do a connection we grab the socket from the connection [Music] and then we will uh async receive and then we need to get a buffer so we can say booth racio stream uh buffer and then let's say buffer.prepare let's say 512 and we will give it a this and const boost system error code error size t bytes transferred here and then here we will say i believe it's going to be similar to here and it's going to be like this and it's gonna be tcp server like oops copy this and put that inside our tcp server and here uh we should uh figure out no break here could count disconnected properly now i think this should be roughly what we need to do let's see what this tells us the file handle supplied is not valid right okay so maybe we need to move this to we can take this exact same thing and move it to tcp connection where it says start we can probably do this and we can change this to socket and then um let's just see what this does and see if this gets us closer to what we're looking for okay that looks okay now let's run the client hello beautiful client close that and then an existing connection was forced to be closed by the remote host so we don't want to throw this because that's shutting down our server we will say client disconnected in bad way right and now let's do this again good and now let's do our client client so connected stop client disconnected in bad way and then we can do something with that probably like call a callback or something like that but with that done we are going to call it a i guess morning because it's quite late for me and we will move on to um actually doing the handshake uh in in in the next video because i think this is enough to get started with and we we've gotten uh quite a bit done we've got a nice little client server thing happening here um the the enhancements we can make to this uh moving forward is our server here right now is you can see it's doing um if you look at our connection here the connection itself is just on on all the connections it's just sending a message and waiting for it to be disconnected so these messages here we're going to want to properly handle uh messages that come in um but also we want to be able to dynamically select what we're going to write to this so this um this here will be we will probably write a function to be able to do this for us so we'll probably add an interface here let's just add the interface for now let's just say void write to connection and then int connection index i don't want that uh we will want to and then we'll probably say uh well for now we'll just use the string message but odds are we'll probably want to do something like template type name t and this will be t message right probably like that that's probably how we want to do it we want to be able to write to the connection then what else do we want to do we want to be able to um receive void uh register uh listen call back and again it's probably gonna we're probably gonna wanna do something like template type name t [Music] and then we'll do like uh int connection index and const and then we will want to have a uh using um like template type name t using using listen listen and call back equal stood function t not t it'd be like void t right so it's going to be a function that gets called with a message and probably be like this and we'd want to include functional right something like this and then we would do like listen call back t call back all right it would be like this yeah and then it would be like this i believe and we want to do that right and it'll be something like that where we will have a interface for writing to a specific connection um we could probably we will need to figure out how we're going to store the connections smarter than just a vector probably um and we would want to register the listen call back here which actually it was it would probably be um [Music] and like this right and then we would just register the list and call back for that type a message like this and write to connection const t this makes sense but we would probably i either we'll do this in another video but this is what i'm thinking well we're going to have an interface where we're going to be able to uh register listeners for each individual type so that when that type is read from a message is received from that type on a connection it would send it back to the main application where it could then be handled and any responses given yeah it's something like this but we'll we'll deal with that later but for now um i'll just generate these definitions so that um my warnings go away they're not being used but if i i can probably build everything now all right so i know i said i was trying to keep it shorter but you know how it goes with me everything seems to be really long processes because i like to make things overly complicated for better for worse you're getting the overly complicated versions so anyways if you liked what we're doing here and you're excited to see more excited for our server to get a little bit more mature and do a little bit more of exciting things uh stick around it's just gonna be another four weeks probably because you know i'm going in order uh i got one topic per week four topics per month and that's the schedule we're gonna stick to so anyways it was fun i'm looking forward to expanding this even more peace [Music]
Info
Channel: Ozzadar
Views: 1,914
Rating: undefined out of 5
Keywords: c++ client server, c++ client server application, c++ client server aplication, client server chat c++, c++ boost, c++ asio, c++ networking, c++ networking tutorial, c++ tutorial, c++ tcp, c++ tcp server, c++ tcp client, ozzadar, client server tutorial, c++ client server tutorial, c++ tcp tutorial, boost asio tutorial, computer networking, computer network, networking, c++, programming, c++ boost asio, c++ asio tutorial, c++ asio tcp server, c++ game networking
Id: DVMHEDhYEr4
Channel Id: undefined
Length: 80min 30sec (4830 seconds)
Published: Sun Aug 22 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.