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 Running
to 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...
And 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 NetworkStream
s. 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 Block
s. 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.