As promised, in this lesson, we're going to go through the code again and explain it with more detail.
We are going to edit the code a bit, so I'm going to add a new package.
I'll name it simple_udp2. And then I'm just going to copy these two classes into this new package.
I'll close the previous two classes
and open the two new ones.
The thing we're going to change is - we're going to allow these two to continue to communicate indefinitely,
but only the sender will be able to enter their message.
The receiver is going to just send - let me see - the receiver can just send "Ok."
This means that I don't really need these lines - I don't need this one and I don't need the Scanner, but
in order to allow them to communicate indefinitely, I'm going to have to add an indefinite loop - and I'm
going to add it right here.
It's going to be >>while<< and the condition is going to be "true", and then I'm going to close this loop right
here.
Now I want to format this better, in order to do that I'm going to select the code that I want to
shift to the right, and I'm going to press Ctrl + Shift + F. "F" is short for "format" and this is what I get
by using it.
So I'm happy with this.
I'm going to save that and move to the Sender.
We need to add the same loop here - and this is where we'll put it.
It's going to be while(true) and we'll close it right here.
We're gonna format this too by pressing
Ctrl + Shift + F. Ok.
That's it - I'm gonna save this, and test if it works. Let's run the Receiver first.
Receiver is running.
That's a good sign.
I'm going to run the Sender
now, and enter something - "hi" - and then, Receiver says: "Ok."
And then I'm going to say "bye" for example, and Receiver again says "Ok."
Now ideally, we would have some kind of verification here - and we would check what did the sender send.
For example, if they send "bye" or "quit" or "exit" - we could break from our loop and end the program.
But I'm going to leave that to you, since we've already done something similar in our previous examples
with TCP,
so you can do the same here, but since this is UDP, and there is no established connection - we can simply
just terminate the sender and then close the console, and then terminate the receiver and close that
console too, without any consequences.
We didn't get any errors.
We didn't get any exceptions.
We were just able to close these two programs without anything really going wrong.
That's because - as I've already mentioned - there are no sessions established between the two.
That's because each packet is built and sent separately, and additionally, we're using UDP - which is pretty
much a "best effort" protocol.
So even if a packet is not delivered to its destination - no worries.
That's how UDP is expected to work.
All right. Let's go through the code.
I'm going to start with the sender, and hopefully you already get the whole point behind the main method.
This is - as I said in our previous, TCP examples - an entry to our application. And then we have the try-
catch block. We try to execute some code in this block, and then if something fails within that code, we
are thrown to the catch block. In the catch block, we've always used this method printStackTrace(), which
pretty much just prints out anything that went wrong - in these red letters in this console area.
So in our try block, we are initiating a new Sender(), and the first thing that happens there is - we create
a DatagramSocket.
This socket is very similar to the regular socket we used in our TCP examples.
It's just a door that we use to throw out the data and receive the new data that's coming in from the
other side.
Then, we have created a System input Scanner that we used to get the data that our user is typing in,
to be sent to the receiver.
So this is where we have used our keyboard scanner to get the message from the user. And then send that
message through the socket. Regarding the while loop,
I added it in this lesson - so you get why I did that.
But let me explain why it's in this place.
I added it here because everything that happens in the body of the loop repeats itself all the time,
and I need these things to repeat because this is the communication between the sender and the receiver.
For example, these two things don't have to happen every time we want to exchange messages between the
sender and the receiver.
They only happen once.
So we need to open a socket only one time.
We have defined our keyboard Scanner only one time. All of the other things do need to happen every single
time
these two want to exchange messages. Every time the sender is sending a message,
we want to print out "Enter your message" to the user.
And then that user enters their message, and we store that message into our message string.
Then we translate that message into bytes, and we store those bytes in our buffer object.
Then we take that buffer where our message is stored, and we put it into our packet.
So what we need to put into the UDP packet - is the payload itself.
So the payload is the message.
That's the useful application data that we are transferring between the two applications.
Then, we need to specify the amount of our data.
That's the length.
And if we look at the UDP header format - this is the field I'm talking about.
So this is the Length field, and then we are specifying the IP address that we're communicating with,
and then we're specifying the destination port.
As soon as we have formed that packet, we can send it out through our socket.
This line below is just a printout for our own console where we are saying "this is what was sent" and
then the rest of the code is the receiving part.
So we needed all of this to send a packet.
But we're going to use all of this to receive a packet.
Let's go through it line by line.
Here we are using the same buffer we used to send a message,
and keep in mind that at this very point - this buffer actually has this message in it.
So that is why we are creating a new array for this very object.
That's because we are going to fill it with the data that we are waiting for.
This is the data that is going to be in the packet that we are receiving here.
Again, we are using an existing object.
So this packet already has some data in it, because we use the same object to send that message that
our user entered.
So now I am creating a new packet that is going to be empty and is going to be ready to receive the
incoming packet.
And that's exactly what I do in this line.
I am looking at the socket and I am saying "Ok, I'm expecting to receive a packet right now. When it comes,
put it into this new object."
So this object isn't new.
It was created earlier to send a packet,
but I have just redefined it in this line here.
And so now it's empty and it's ready to receive the new packet. As soon as I have received the packet,
I'm going to extract the string from the packet. That string - or that message - is inside of a buffer.
So I want to use this new string to again do pretty much the same thing I did here.
I want to reuse this message string, but I'm going to have to extract that message from my buffer.
Additionally, when I extracted the message from the buffer, I need to trim it, because as I mentioned while
we were creating these two classes, this buffer is 1500 bytes long,
and the message that I've received may be shorter.
So this trim() method is used to cut all of that excess data, and then again, the next line is just a printout
of the message that we received.
All right.
That's the sender.
Let's go back to the receiver.
The main method here is again the same main method we've used throughout this course.
So I'm going to skip that. The first thing we see is the DatagramSocket -
It's similar to the sender DatagramSocket. Only at the receiver
end, we have defined the listening port number. And then we've used this printout saying "Receiver is running."
This is just for tracking purposes, to see if we've gone through this line of code correctly.
And then we get into our loop. Here we have the receiving part, and it's very similar to what we have
in the sender.
So I'm going to just skip that.
The only difference we have is this part. At the sender, since the sender is the first one to send a packet,
we had to define the destination IP address and the destination port number. But since the receiver
is just replying to the sender, the receiver can just pull out the sender's IP address.
So the source IP address from the packet, and the senders source port number.
So here - the receiver is getting that information from the packet, and then is using that same information
to create the new packet that it's going to send back to the sender.
That's pretty much everything that happens in this part.
And then we're left with only the printout, which is as always, only giving us a notification in our console
part, to let us know where we're at, and what is happening.
And in this case what was sent to the sender.
That's it for this lesson.
If there's anything else you'd like to know or something you think I could help you with,
send me a message or post it in the Q&A section, and I'll make sure to try and help you if I can.