Welcome!

Microsoft Cloud Authors: Pat Romanski, Andreas Grabner, Nick Basinger, Kevin Benedict, Liz McMillan

Related Topics: Microsoft Cloud

Microsoft Cloud: Article

A File Transfer Application from Professional .NET Network Programming

A File Transfer Application from Professional .NET Network Programming

(March 7, 2003) - Networking is one of the core tasks of enterprise-level programming, and for the programmer familiar with the C# language, Professional .NET Network Programming will provide the information to put network programming at the heart of their .NET applications. The following is an excerpt from this recent book from Wrox Press.

A File Transfer Application

We have seen how to use the UdpClient class to send and receive datagrams, and we created a chat application using the same principle. Next, we'll see how to transfer a file and serialized object using UdpClient. The sender and receiver programs are divided into two logical parts. In the first part, the sender sends file details (namely the file extension and file size) to the receiver(s) as a serialized object, and in the second part the actual file is sent to the destination. In the receiver, the first part accepts the serialized object with the associated information, and in the second part it creates the file on the destination machine. To make the application more interesting, we'll open the saved file using the associated program (for example, a .doc file might be opened with Microsoft Word, or an .htm file with Internet Explorer).

File Server

The file server is a simple console application implemented in a class named FileSender. This has a nested class called FileDetails that contains the information about the file - the file size and the file type. We start by importing the necessary namespaces, and declaring the fields for the class. The class has five private fields - an instance of our FileDetails class, a UdpClient object, plus information about the connection to the remote client, and a FileStream object for reading in the file we'll send to the client:

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Threading;

public class FileSender
{
private static FileDetails fileDet = new FileDetails();

// UdpClient-related fields
private static IPAddress remoteIPAddress;
private const int remotePort = 5002;
private static UdpClient sender = new UdpClient();
private static IPEndPoint endPoint;

// Filestream object
private static FileStream fs;

Next we define the FileDetails class. Our FileDetails object will need to be serialized for sending over the network, so we add the [Serializable] attribute. As we've already intimated, the class just has two public fields, to store the type and the size of the file:

// File details (Req. for receiver)
[Serializable]
public class FileDetails
{
public string FILETYPE = "";
public long FILESIZE = 0;
}
Now we come to the Main() method for the server. In this method we invite the user to input a remote IP address to send the file to, and then to enter the path and filename of the file to send. We open up this file with the FileStream object, and check its length. If this is greater than the maximum permitted size of 8,192 bytes, we close the UdpClient and the FileStream, and exit the application. Otherwise, we send the file information, wait two seconds by calling the Thread.Sleep() method, and then send the file itself:

[STAThread]
static void Main(string[] args)
{
try
{
// Get remote IP address and create IPEndPoint
Console.WriteLine("Enter Remote IP address");
remoteIPAddress = IPAddress.Parse(Console.ReadLine().ToString());
endPoint = new IPEndPoint(remoteIPAddress, remotePort);

// Get file path. (IMP: file size should be less than 8K)
Console.WriteLine("Enter File path and name to send.");
fs = new FileStream(@Console.ReadLine().ToString(), FileMode.Open,
FileAccess.Read);

if (fs.Length > 8192)
{
Console.Write("This version transfers files with size < 8192 bytes");
sender.Close();
fs.Close();
return;
}

SendFileInfo(); // Send file info to receiver
Thread.Sleep(2000); // Wait for 2 seconds
SendFile(); // Send actual file
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}

The SendFileInfo() method populates the fields of the FileDetails object, and then serializes this object into a MemoryStream, using an XmlSerializer object. This is then read into a byte array, which is passed into the UdpClient's Send() method, to send the file information to the client:

public static void SendFileInfo()
{
// Get file type or extension
fileDet.FILETYPE = fs.Name.Substring((int)fs.Name.Length - 3, 3);

// Get file length (Future purpose)
fileDet.FILESIZE = fs.Length;

XmlSerializer fileSerializer = new XmlSerializer(typeof(FileDetails));
MemoryStream stream = new MemoryStream();

// Serialize object
fileSerializer.Serialize(stream, fileDet);
// Stream to byte
stream.Position = 0;
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, Convert.ToInt32(stream.Length));

Console.WriteLine("Sending file details...");

// Send file details
sender.Send(bytes, bytes.Length, endPoint);
stream.Close();
}

The SendFile() method just reads the file content from the FileStream into a byte array, and then sends this to the client:

private static void SendFile()
{
// Creating a file stream
byte[] bytes = new byte[fs.Length];

// Stream to bytes
fs.Read(bytes, 0, bytes.Length);

Console.WriteLine("Sending file...size = " + fs.Length + " bytes");
try
{
sender.Send(bytes, bytes.Length, endPoint); // Send file
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
// Clean up
fs.Close();
sender.Close();
}

Console.Read();
Console.WriteLine("File sent suceessfully.");
}
}

File Receiver The file receiver is again a console application, and is implemented in a class named FileRecv. Again, we start by importing the necessary namespaces and declaring the fields for the class:

using System;
using System.IO;
using System.Net;
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Xml.Serialization;

public class FileRecv
{
private static FileDetails fileDet;

// UdpClient vars
private static int localPort = 5002 ;
private static UdpClient receivingUdpClient = new UdpClient(localPort);
private static IPEndPoint RemoteIpEndPoint = null ;

private static FileStream fs;
private static byte[] receiveBytes = new byte[0];

We will need to deserialize the file information sent from the server into a FileDetails object, so we need to define that class within the client application, too:

[Serializable]
public class FileDetails
{
public string FILETYPE = "";
public long FILESIZE = 0;
}

The Main() method for the application just calls two methods, to get respectively the file details and the file itself:

[STAThread]
static void Main(string[] args)
{
// Get the file details
GetFileDetails();

// Receive file
ReceiveFile();
}

The GetFileDetails() method calls the Receive() method of the UdpClient object. This receives the serialized FileDetails object from the server, which we save to a MemoryStream. We use an XmlSerializer object to deserialize this stream back into a FileDetails object, and display the retrieved information in the console:

private static void GetFileDetails()
{
try
{
Console.WriteLine(
"-----------*******Waiting to get File Details!!*******-----------");
// Receive file info
receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
Console.WriteLine("----Received File Details!!");

XmlSerializer fileSerializer = new XmlSerializer(typeof(FileDetails));
MemoryStream stream1 = new MemoryStream();

// Received byte to stream
stream1.Write(receiveBytes, 0, receiveBytes.Length);
stream1.Position = 0; // IMP

// Call the Deserialize method and cast to the object type.
fileDet = (FileDetails)fileSerializer.Deserialize(stream1);
Console.WriteLine ("Received file of type ." + fileDet.FILETYPE +
" whose size is " + fileDet.FILESIZE.ToString () + " bytes");
}
catch (Exception e)
{
Console.WriteLine (e.ToString ());
}
}

The ReceiveFile() method retrieves the file from the server and saves it to disk with the filename temp, plus the extension retrieved from the FileDetails object. We then call the Process.Start() static method to open the document with the associated program:

public static void ReceiveFile()
{
try
{
Console.WriteLine(
"-----------*******Waiting to get File!!*******-----------");
// Receive file
receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);

// Convert and display data
Console.WriteLine("----File received...Saving...");

// Create temp file from received file extension
fs = new FileStream("temp." + fileDet.FILETYPE, FileMode.Create,
FileAccess.ReadWrite, FileShare.ReadWrite);
fs.Write(receiveBytes, 0, receiveBytes.Length);

Console.WriteLine("----File Saved...");
Console.WriteLine("-------Opening file with associated program------");

Process.Start(fs.Name); // Opens file with associated program
}
catch (Exception e)
{
Console.WriteLine(e.ToString ());
}
finally
{
fs.Close();
receivingUdpClient.Close();
}
}
}

Here's the output on the client and server when we run this program: See Figure 1.

This application has some limitations; firstly, the size of the file depends upon the size of the internal message buffer or network limit. The default buffer size is 8,192 bytes, so we cannot send files larger than 8,192 bytes. This could be overcome by dividing the file into multiple segments, each with a buffer size of 8,192 bytes. By calling the Read() method with the required buffer size, we can divide the file into multiple segments.

As UDP does not use acknowledgement signals, we would have to implement a separate mechanism to check whether each segment was received correctly or not before sending the next segment. This can be achieved by creating another instance of UdpClient in both the sender and receiver, which will check for acknowledgement messages.

Professional .NET Network Programming, by Christian Nagel, Srinivasa Sivakumar, Andrew Krowczyk, Tim Parker, Ajit Mungale, Nauman Laghari, and Vinod Kumar was published by Wrox Press in October 2002. ISBN: 1-861007-35-3. 496 pages, $49.99. For more information, see http://www.wrox.com/books/1861007353.htm ">http://www.wrox.com/books/1861007353.htm.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


IoT & Smart Cities Stories
Moroccanoil®, the global leader in oil-infused beauty, is thrilled to announce the NEW Moroccanoil Color Depositing Masks, a collection of dual-benefit hair masks that deposit pure pigments while providing the treatment benefits of a deep conditioning mask. The collection consists of seven curated shades for commitment-free, beautifully-colored hair that looks and feels healthy.
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
The textured-hair category is inarguably the hottest in the haircare space today. This has been driven by the proliferation of founder brands started by curly and coily consumers and savvy consumers who increasingly want products specifically for their texture type. This trend is underscored by the latest insights from NaturallyCurly's 2018 TextureTrends report, released today. According to the 2018 TextureTrends Report, more than 80 percent of women with curly and coily hair say they purcha...
We all love the many benefits of natural plant oils, used as a deap treatment before shampooing, at home or at the beach, but is there an all-in-one solution for everyday intensive nutrition and modern styling?I am passionate about the benefits of natural extracts with tried-and-tested results, which I have used to develop my own brand (lemon for its acid ph, wheat germ for its fortifying action…). I wanted a product which combined caring and styling effects, and which could be used after shampo...
The platform combines the strengths of Singtel's extensive, intelligent network capabilities with Microsoft's cloud expertise to create a unique solution that sets new standards for IoT applications," said Mr Diomedes Kastanis, Head of IoT at Singtel. "Our solution provides speed, transparency and flexibility, paving the way for a more pervasive use of IoT to accelerate enterprises' digitalisation efforts. AI-powered intelligent connectivity over Microsoft Azure will be the fastest connected pat...
There are many examples of disruption in consumer space – Uber disrupting the cab industry, Airbnb disrupting the hospitality industry and so on; but have you wondered who is disrupting support and operations? AISERA helps make businesses and customers successful by offering consumer-like user experience for support and operations. We have built the world’s first AI-driven IT / HR / Cloud / Customer Support and Operations solution.
Codete accelerates their clients growth through technological expertise and experience. Codite team works with organizations to meet the challenges that digitalization presents. Their clients include digital start-ups as well as established enterprises in the IT industry. To stay competitive in a highly innovative IT industry, strong R&D departments and bold spin-off initiatives is a must. Codete Data Science and Software Architects teams help corporate clients to stay up to date with the mod...
At CloudEXPO Silicon Valley, June 24-26, 2019, Digital Transformation (DX) is a major focus with expanded DevOpsSUMMIT and FinTechEXPO programs within the DXWorldEXPO agenda. Successful transformation requires a laser focus on being data-driven and on using all the tools available that enable transformation if they plan to survive over the long term. A total of 88% of Fortune 500 companies from a generation ago are now out of business. Only 12% still survive. Similar percentages are found throug...
Druva is the global leader in Cloud Data Protection and Management, delivering the industry's first data management-as-a-service solution that aggregates data from endpoints, servers and cloud applications and leverages the public cloud to offer a single pane of glass to enable data protection, governance and intelligence-dramatically increasing the availability and visibility of business critical information, while reducing the risk, cost and complexity of managing and protecting it. Druva's...
BMC has unmatched experience in IT management, supporting 92 of the Forbes Global 100, and earning recognition as an ITSM Gartner Magic Quadrant Leader for five years running. Our solutions offer speed, agility, and efficiency to tackle business challenges in the areas of service management, automation, operations, and the mainframe.