UDP File Transfer - Receiver
This is what requests a file from a Sender and downloads it to a local machine. Just like with the other program you can twiddle with some of the hard coded arguments and replace them with command line ones in the Main()
function at the bottom.
Like with the Sender, in our constructor we create our UdpClient
with a default remote host set (which should be that of the Sender).
I mentioned in the last part that there is a Connect
method in UdpClient
(doc link). Please note that this is a dirty filthy lie as UDP is a connectionless protocol. In reality, what it does is set a "default remote host," for you so every time that you call this overload of the Send
method you don't need to specify where you want to go, as it will only go to that one host. This also applies to some of the constructors for UdpClient
(like the one we're using).
Shutdown()
in this class will just request a cancel of an existing file transfer, you can see later in the GetFile()
method how this works.
GetFile()
is the most important function of the class and its very similarly structured to UdpFileSender.Run()
. It's what does all of the communication with the Sender. Let's break it down. Up at the top of the function's body there are some variables for the file transfer state and a helper function to reset them if needed. In the beginning of the while
loop we check for any new NetworkMessage
s. First checking if the latest received Packet
is a BYE
, it then passes that onto the switch
statement. Inside of the switch
is what manages the state of the file transfer (REQF
, wait for ACK
, wait for INFO
, ACK
, etc...). Inside of the ReceiverState.Transfering
case
it will empty the Block
request queue, check for any SEND
messages (i.e. Block
data). If the request queue is empty but we don't have all the Block
s, it will refill the request queue with the missing Block.Number
values. But if we have all of the Block
s, then we move onto the state where we say BYE
to the Sender (so it can accept new transfers) and then we reconstruct the Block
s into a byte array, uncompress them, and save the file. At the end of the function we make a check to see if the transfer was ended prematurely by user request or the Sender.
Close()
will clean up the underlying network resources, which is just the UdpClient
.
_checkForNetworkMessages()
is identical to the one seen in Sender. It sees if there are enough bytes for a Packet
message then queues it up for processing.
_saveBlocksToFile()
is where we take the Block
s, reassemble them, uncompress the data, verify it with a checksum and then save it to the disk.