UDP File Transfer - Sender
Here is what will wait for file requests and respond to them. This acts as a server of sorts. Note that in
Main() you can comment out the hard coded arguments and used command line args instead.
So there is quite some code here, let's break it down.
In the constructor for
UdpFileSender, we tell it what directory we want to use for files that are able to be transferred and we create the
UdpClient. We create it to listen for incoming datagrams on a specific port, and only IPv4 connections.
Init() will scan the
FilesDirectory (non-recursively) for any files and mark them as transferable. It also sets
true so we can start listening for Receivers.
Shutdown() is used to simply shut down the "server."
Run() is the main meat of
UdpFileSender. At the top we have some variables that are used for the transfer state as well as a mini-helper function to reset the state in case we have to. In the beginning of the loop we see if we have any new Packets that were sent to us. If one was a
BYE message, it means the client has prematurely disconnected and we should reset the transfer state to wait for a new client. The switch statement is used to run through the transfer process. Each state will wait for a certain type of
Packet, do some processing (e.g. creating a response or preparing a file for transfer) then move to the next one in line. I won't go into the gory details as it's pretty easy to read (IMO). At the bottom of the while loop we take a short nap to save on CPU resources. And at the end of the function we send a
BYE message to a client if we have one currently "connected," (in case the Sender operator wanted to shut down in the middle of a transfer).
Talking about the
Send method of
UdpClient, we are using the overload that requires you list and endpoint. If you application may connect with multiple clients, I recommend using this method over the other ones. Reminder that UDP is connectionless, therefore we don't have an established connection with any client. Please ignore that
Connect method you might have seen for now...
Close() will clean up the underlying
UdpClient; 'nuff said.
_checkForNetworkMessages() will see if we have any new datagrams that have ben received. Since all of our Packets are at least four bytes in length, we want to make sure that many bytes are ready. We create a dummy
IPEndPoint object. Using
UdpClient.Receive, it will grab exactly one datagram that has been received by the network. Unlike
TcpClient, we don't have to mess around with
NetworkStreams. After we have it, we shove its sender and the
Packet into a
NetworkMessage queue for later processing.
_prepareFile() will do what the name implies and makes a file ready for transfer. It takes in a filepath, computes a checksum of the original bytes, compresses it, and chops it into
Blocks. If all went well, it will return
true, and its
out parameters will be populated. If you missed my last tutorial on Compression in C# be sure to read it, find it over here.
That's really all there is to
UdpFileSender. If you glossed over the switch statement in
Run() that handles the state of the file transfer process, I recommend you read it well.