 Some people are going to love this video, and some people are going to hate this video. What we're going to do is we're going to create a ping utility. If you have no idea what ping is, well, ping operates by sending ICMP echo request packets to a host and getting their response back. The whole point of this is to determine, A, is that end host even up and running, and B, how long does it take to get a response back? So for example, ping, we're going to ping example.com. It's going to go through multiple hoops. We want to know the time to live and, of course, the most important bit, how long it took to get that response back at each network hop. Now this is networking 101, and this gets a little bit complex under the hood, but basically we use ping to determine is it running and how long does it take to get a response back. This also is very, very complex under the hood. You're talking about a special way of using a socket, and you have a protocol you have to work with. On top of that, the ports you use to do this communication in some operating systems are administratively controlled ports. I think it's like 1 through 1024, you have to run as an administrator or as root or with root privileges to do this. So this gets very complex very, very quickly. We are going to use Q process, and if you read the description of Q process, it says the Q process class is used to start external programs and communicate with them. So ping already exists out on your system. So in the interest of design patterns, one of them is not reinventing the wheel or keep it simple. So what's the point of recreating from scratch an entirely new ping utility when one already exists on your operating system? It works just fine. It's been completely and thoroughly bug tested and version upgraded and everything you can possibly imagine. There's no point in reinventing the wheel here. So we're just going to use Q process. Now this will make people mad because some people tend to want to over engineer a solution and they're going to want to go out and grab some sort of like library or classes that has ping wrapped into it and then roll that directly into their application. But then they run into issues down the road where their application simply won't run without root privileges. So we're going to bypass all of that and use Q process. If you're unfamiliar with Q process, really what this does under the hood is something like this. You make a process and you say process start a program with a list of arguments and then from there you enter into a communication state where you can send it commands and get the responses back. We have a very bare bones application. This is just a widgets app. We're going to say what OS we detected along with you guessed it the IP address and the responses. Now this is not the remote OS. This is our local OS under the hood here. There's absolutely nothing going on in this dialogue. It's very blank. We're going to fill all that in and our main is the same way. I've just got some notes in there. So the thing we're going to try to accomplish is using Q process to call another app. We're going to let the OS and its applications do the work for us. Why? We don't want to reinvent the wheel. It's hard requires admin access and usually has a steep learning curve, especially if you are brand new to networking. So let's dive in. First things first, let's give our code a good build. Make sure there's no little gremlins and let's actually run it and see what this looks like. So when this starts up, we're going to want to detect what OS we're running on and then we want to be able to start pinging and stop pinging. Let's go ahead and create a new class. And let's call this ping. Now I should note that Q process is not limited to just ping. You can run any application. The problem with running any application is every application is, well, you guessed it, different under the hood and will respond and behave differently and even across different operating systems. So what we're going to do now is we're going to add some private stuff in here. Q process, Q string, a bull called listening, a get process and a start ping. So let's go ahead and flush these out. And this code is not overly complex, but there is a good chunk of it. So I'm going to be doing quite a bit of copy and pasting. Let's go ahead and grab that off the screen and bang. Now you see what I mean here. So we want an operating system getter. We want to be able to get the address and set the address. That is our getter and setter for this guy right here. And then we have a signal called output. And then we have some public slots start and stop. And we have some private slots. And this is what we're actually communicating with Q process. So Q process is going to emit some signals, those being error occurred, finished, ready read standard error, ready read standard output started state change and ready read, which I believe is a combination of these two. All right, that's a bit. So let's go ahead and flush all these out. We're going to implement these almost implemented a signal that would have been really, really interesting. This is what I call the boring part or the plumbing. Feel free to fast forward through this bit. I actually in every single language, this is the part I've always just disliked about coding is just connecting everything up. All right, we should have everything. Let's go ahead and give this a build. Got a whole ton of warnings, which is okay. Let's go ahead and jump in here. And first things first, we need to connect up some signals and slots. And I'm going to because there's a lot of them through the old copy and paste. You see right off the bat, got some stuff in here. So we're going to connect our process, error occurred, ready, ready, read standard error, ready read standard output started state change and ready read to this objects exact same slots. Notice, especially here, finish is overloaded. So we have to do this a little bit differently here. But this is ripped straight out of the Qt documentation. We're saying the end process and we want to know you guessed it, the finished to our finish. And this is going to be the Qt process exit status. So it looks ugly and nasty, but that's how you have to connect an overloaded signal and slot from there. What we're going to do is set some variables. I'm saying I'm listening for faults. And then let's go ahead and set our address. Now our operating system is just going to return the Q sys info and we want the operating system. Actually, we want the pretty product name. Sorry. If you've never used that before, what that does is that returns a nice neat little string representation of what the operating system is. So they'll say like, if you're on windows, they'll say like windows 10 and then whatever your version is. All right. From here, we've got some functions we need to fill out. But guess what? This is actually pretty straightforward. It looks like it's going to be daunting, but it's really, really not bad. So what I'm going to do here is go into Ping. I'm going to say Q info. Ping start is going to, I just want to know the function information. So I'm say Q funk info. This is just going to print out the function and where we are in the file and that sort of stuff. It's just for debug purposes in case we have any issues later on. Then I want to say listening is true. And then end process. We're going to go ahead and start. And we're going to get the process. Now we're doing this in a cross platform fashion. So each platform is going to have a different process. And don't worry. It's not super bad. What we're going to do is we're going to start either bash or command. What is it? CMD.exe on windows. So we need to know which process we're actually going to start. So it's the same thing as saying, hey, we're going to open a command line in the background. And then we're going to ping something. So rather than calling ping directly, that's what we're going to be doing here. Okay, now we're going to do pretty much the exact opposite for stop. We're going to say listening falls process close. Notice how we're just saying close. We don't care what's going on anymore. We're done with it. Now error occurred. This is where we're going to say, hey, if we're not listening, go ahead and get out of here. We want to know the function information along with the error message. And then we're going to emit our output error finished pretty straightforward. If we're not listening, break out of here. And then we got some QNUs and then we're just emitting a signal. Now our ready read standard error. Let's take a look at this. We are going to break out if we're not listening, return the function information. And then we're going to say, go ahead and read all of the standard error. And then we're just going to output that message. It's pretty simple. We're not doing any real voodoo magic here. We just want to know, hey, something was emitted from that process. Ready read standard output, pretty much the same thing. We're just going to go ahead and grab all of that. Now you notice the read all. I've said in the past, don't do read all. This is not going to be terabytes of information, so it's perfectly fine to do that. All right, started. We are going to do absolutely nothing. So we just want to know that started was called state changed. This is where it gets a little bit interesting. What we're talking about in the state change here is we're saying, hey, the process has now entered a new state and it's either not running started or running. So not running is the same as the application is just not there. Starting is the startup part of the application. When you first like double click an app, how it's kind of like loading up in memory, that's what's going on. And then running is when it's happily running away. And when it's running, we want to start the ping. Okay, we've got a few left and I know I've kind of whipped through here. But again, this code is not like award winning code. It's very, very simplistic. I didn't want to waste a lot of time typing it all out. Ready read very, very simple. We're just going to grab that process read all trimmed. So we remove any trailing spaces or anything like that. And then again, we're just going to emit the output. So the whole point of this class is we're really just emitting output. Whatever we got from that process. So whatever it's going to return, we're just going to emit back out and say, this is what we got. All right, get process. This is where I may slow down just a little bit here. So I'm going to say Q info. And I want the Q funk info. Sounds like a term out of the 70s. Like when you go to the disco, you want the Q funk info. But anyways, if and I want to say Q sys info. And I want the product type. Now, if this is windows, I want to return. And this is where you're going to want to tweak this for. If you're doing this in like a production base, or if you've got a different operating system. So on windows, we're going to return CMD, which is the command line for non windows. We would want to return something else. So like OS X. I think it is, and I'm going from memory here, bin slash. What is it? ZSH. And then for anything else. We're just going to return bash or the born again shell. Now, if you wanted something different, that is where you would go in and go just plug in whatever you want. But basically you want the terminal or the command line for your operating system. The same thing as this right here. And then start ping. This is pretty simple. Actually, this is where we would actually start the ping application on that command line. So we're going to say, the command is going to be ping and the address. And then we're going to say, if it is windows, we have this special character turn and then everything else is going to have a line feeding, including windows. And then the process, we're going to write that command out. So it's the same thing as doing this. I'm going to say ping, whatever the address is, I'm saying 192.168.1.1. That's my router sitting in front of me. And then it's going to do something like this and return some output. And because we've connected all those signals and slots, we should be able to read all that output. Now, before you get all excited, this would be your local network. If you don't know anything about networking, this is networking 101. So this is our local network. We're not going out into the internet or anything like that. And if you were to ping this address, it may or may not work because I don't know what your router at your home is. And if you ping this and get excited, no, it's not my router. It's your router. If you have no idea what to work with, you can use what's called your local loopback address. And it's 127.0.0.1. And every single system everywhere has this. This is built right into the networking stack. It's called your local loopback. This is literally your device. So you're pinging yourself. And you can see pinging yourself is incredibly fast. Okay. So in a nutshell, that is our little ping class. We've got a few things we need to get here. So we need to get the address, which should just return mAddress. And setting the address, of course, we'll say mAddress equals the address. So now we've got our getter and setter in there. Major caveat here is you want to know in advance what type of operating system you're running. And if you want to do something different than what I've done, you're going to want to do it here in the get process. And from here, all we're really doing is launching a command line, whatever that command line is, and then launching an application with some type of parameter here and then getting the response back. And that's why some people will love this and some people hate it because it is overly simplified. But at the same time, it usually just works. All right. Now we're going to go ahead and integrate this into our dialogue. So I'm going to say include. We're going to include ping. From here, it's very, very simple. I say that, but we'll probably end up having errors that I'm going to have to go in and fix. All right. So now I want to do, you guessed it, some input and output here. So we've got our ping in there. Let's go ahead and I want some slots here. So our private slot is going to be our output. This is going to match right up with our output signal. So it's the same thing as just grabbing this, copying it, and then going into our dialogue and pasting it. Then I'm going to drop into the UE. I call it the UE, the GUI, sorry. And I want to right click and we're going to go to slot. And I want to know when that text change, meaning when somebody types something. And it drops us right into the implementation and we're exactly where we need to be. So from here, I'm going to say UI and I want the OS. Go ahead and set text on that. And I'm going to say OS detected. And this is where we're going to just say, this is the operating system we got here from our ping class. And it should just turn that pretty operating system name. Let's go ahead and test that real quick. Make sure that's working. Uh-oh. Undefined reference to dialogue output. We can fix that super fast, but that error message always throws me off. There we go. All right. So OS detected. I am on Linux meant yours will say whatever operating system you're on, but that is the pretty OS name. So this is not the remote host. This is your local system. I put this in here in case you're having some sort of issue running this and you don't even know how to find your operating system. You just look right at it and say, oh, I need to know the command line application for whatever this is. And you can find that usually out on Google very, very quickly. From here, it's very, very straightforward. We're going to just say, okay, ping, set the address to whatever the text is, and then connect up our signals and slots. And we're going to connect the start, stop, and then our output to our output. And I swear I just heard thunder in the background. I hope not. If the microphone picked that up, I apologize, but I swear I heard something. And then on our output, we're going to say plain text edit. We're going to go ahead and append plain text. And we're going to append whatever the data is. And this is the signal that was emitted from our process, or our ping who's monitoring Q process in the background. And then you guessed it. It's just very simple. Whenever the user types something, we want to go ahead and set the address to whatever they typed. That's pretty much it in a nutshell. This is why I prefer this method, because we can actually build a rather complex little application very, very quickly. All right, now, let's go ahead and we've got our buttons wired up here. Let's go ahead and start. You can see I am now paying. And I can stop this. Very simple, very easy to use, and it just works. And you can take this and modify it to run, not just ping, but pretty much any process out there. So if you had some special application like you wanted to zip a file or something, you can actually do the same thing. You just need to know what application you're calling, what parameters it's expecting, and know how to read the response back, which just to recap, we are doing that in the ready read and in the ready read standard error and standard output.