Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

A Client Server File Sharing Application

, 2 Feb 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
A Client Server File Sharing Application

Jan 15, 2011. 5:15 PM

This blog post is a client/server file sharing or transfer application in C#, the application is made up of two projects, it can be tested on a single computer but its capability will be best seen if tested on two computers, one running as a client while the other is a server.

Before we dive into coding, it is essential to understand Socket which is the most important aspect of network programming.

Socket is an object that represents a low level access point to the Internet Protocol(IP) stack, it is used to send and receive data, thus it can be opened and closed, the data to be sent is always sent in block known as Packet.

Packets must contain the IP address of both the source of the packets and the destination computer where the data is being sent, and optionally it may contain a Port number. A port number is between 1 and 65,535. A port is a communication channel or endpoints on which computers can communicate. It is always recommended that programs use port number higher than 1024 to avoid conflicts with other applications running on the system, because no two applications can use the same port.

Packets containing port numbers can be sent using UDP (User Datagram Protocol) or TCP/IP(Transmission control protocol). UDP is easier to use than TCP because TCP is more complex and has longer latencies, but when the integrity of the data to be transferred is more important than performance, then TCP is preferred to UDP, and thus for our file sharing application TCP/IP will be used because it guarantees that our file does not become corrupt while being transferred and if during the transmission process a packet is loss, it is retransmitted thus making sure that our file integrity is maintained.

Thus, this application will allow you to send any file from one computer to another, personally I have used it to send a 350MB file from one desktop PC to another.

Now to get started, create two new Windows Forms applications. one named FileSharingServer and the other FileSharingClient.

Now, for the FileSharingClient Windows Form application, add three textboxes and two buttons to the form just like the screen below:

filesharingclient

Rename the textboxes and buttons appropriately.

This is the code for the file sharing client application:

using System;
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Threading.Tasks; 
using System.Net; 
using System.Net.Sockets;
using System.Net.NetworkInformation; 
using System.IO;
namespace FileSharingClient 
{ 
public partial class Form1 : Form 
{
private static string shortFileName = "";
private static string fileName = ""; 
public Form1()
{ 
InitializeComponent();
} 
private void btnBrowse_Click(object sender, EventArgs e) 
{ 
OpenFileDialog dlg = new OpenFileDialog(); 
dlg.Title = "File Sharing Client"; 
dlg.ShowDialog(); 
txtFile.Text = dlg.FileName; 
fileName = dlg.FileName; 
shortFileName = dlg.SafeFileName; 
}
private void btnSend_Click(object sender, EventArgs e) 
{ 
string ipAddress = txtIPAddress.Text; 
int port = int.Parse(txtHost.Text); 
string fileName = txtFile.Text; 
Task.Factory.StartNew(() => SendFile(ipAddress,port,fileName,shortFileName) ); 
MessageBox.Show("File Sent"); 
}
public void SendFile(string remoteHostIP, int remoteHostPort, 
    string longFileName, string shortFileName) 
{ 
try
{ 
if (!string.IsNullOrEmpty(remoteHostIP)) 
{ 
byte[] fileNameByte = Encoding.ASCII.GetBytes(shortFileName); 
byte[] fileData = File.ReadAllBytes(longFileName); 
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length]; 
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length); 
    fileNameLen.CopyTo(clientData, 0); 
fileNameByte.CopyTo(clientData, 4); fileData.CopyTo(clientData, 4 + fileNameByte.Length); 
TcpClient clientSocket = new TcpClient(remoteHostIP, remoteHostPort); 
NetworkStream networkStream = clientSocket.GetStream(); 
    networkStream.Write(clientData, 0, clientData.GetLength(0));
networkStream.Close(); 
} 
}
catch 
{
}
}
} 
}
} 

Note the following namespaces were added to the Windows Form application:

System.Threading.Tasks; // used to include the .NET Parallel computing lclasses

System.Net;
System.Net.Sockets;
System.Net.NetworkInformation; 

The above three namespaces contain the .NET classes used for Network programming.

System.IO; // contain classes used for file operations

When the browse button is clicked, an object of OpenFileDialog is created to open a dialog to get the file name of the file to be sent. When the send button is clicked, the SendFile method is called and handled in parallel so that the main form user interface does not get frozen while the file is being sent and the processors are fully utilized in a multi-core environment.

The SendFile method accepts IP address and port number of the destination computer as well as the file path and file name. Both the file name and the file are converted to bytes and sent to the destination computer using the TCPCLient and NetworkStream classes object created.

The user interface of the file sharing client application is shown below when run.

filesharingclient2

The source code for the server is:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Net; 
using System.Net.Sockets; 
using System.Net.NetworkInformation; 
using System.IO; 
using System.Threading.Tasks; 
namespace FileSharingServer 
{ 
public partial class Form1 : Form 
{ 
public delegate void FileRecievedEventHandler(object source, string fileName); 
public event FileRecievedEventHandler NewFileRecieved; 
public Form1() 
{ 
InitializeComponent(); 
} 
private void Form1_Load(object sender, EventArgs e) 
{ 
this.NewFileRecieved+=new FileRecievedEventHandler (Form1_NewFileRecieved);
} 
private void Form1_NewFileRecieved(object sender, string fileName) 
{
this.BeginInvoke( new Action( delegate() 
    { MessageBox.Show("New File Received\n"+fileName); 
System.Diagnostics.Process.Start("explorer", @"c:\"); 
})); 
} 
private void btnListen_Click(object sender, EventArgs e) 
{ 
int port = int.Parse(txtHost.Text); 
Task.Factory.StartNew(() => HandleIncomingFile(port)); 
MessageBox.Show("Listening on port"+port); 
} 
public void HandleIncomingFile(int port) 
{ 
try 
{ 
TcpListener tcpListener = new TcpListener(port); 
tcpListener.Start(); 
while (true) 
{ 
Socket handlerSocket = tcpListener.AcceptSocket(); 
if (handlerSocket.Connected)
{ 
string fileName = string.Empty; 
NetworkStream networkStream = new NetworkStream(handlerSocket); 
int thisRead = 0; 
int blockSize = 1024; 
Byte[] dataByte = new Byte[blockSize]; 
lock (this) 
{ 
string folderPath = @"c:\"; 
int receivedBytesLen = handlerSocket.Receive(dataByte); 
int fileNameLen = BitConverter.ToInt32(dataByte, 0); 
fileName = Encoding.ASCII.GetString(dataByte, 4, fileNameLen); 
Stream fileStream = File.OpenWrite(folderPath + fileName); 
fileStream.Write(dataByte, 4+fileNameLen,(1024-(4+fileNameLen)));
while (true) 
{ 
thisRead = networkStream.Read(dataByte, 0, blockSize); 
fileStream.Write(dataByte, 0, thisRead); 
if (thisRead == 0) 
break; 
} 
fileStream.Close(); 
} 
if (NewFileRecieved != null)
{ 
NewFileRecieved(this, fileName); 
} 
handlerSocket = null; 
} 
} 
} 
catch { } 
}
}
} 

filesharingserver filesharingserver2

At the file sharing server application, a port number is supplied, on which the server will be listening to an income file to be received.

Just like the file sharing client application, the start listening button when clicked, invokes the HandleIncomingFile method in parallel. A TcpListener object is created to start listening for incoming file at the specified port, when a connection is received then a file with the same name as the file sent from the client is reconstructed from the received bytes and saved to the C drive and then an event is fired to indicate on the server user interface that a new file has been received.

When the event is fired, all subscribers to the event are notified and in this case the event handler method Form1_NewFileRecieved is invoked and the code to display a message box and open the folder containing the file received is wrapped around the form BeginInvoke method to avoid thread errors.

The complete source code of the two applications is available for download here.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Ayobami Adewole
Software Developer Teqbridge Limited
Nigeria Nigeria
A Microsoft Certified Solutions Developer (MCSD), DZone.com Most Valuable Blogger (MVB). Passionate about Sofware Development and VoIP
Follow on   Twitter

Comments and Discussions

 
QuestionC# PingroupNicky Ralph10-Sep-14 22:38 
Questionudp file sharing PinmemberMember 967546721-Dec-12 16:27 
QuestionSending of file does not work Pinmemberjosemartins29-Nov-12 5:19 
AnswerRe: Sending of file does not work Pinmemberjosemartins4-Dec-12 0:24 
Questionwhy uses 4? PinmemberOracle2k18-Jul-12 19:01 
GeneralMy vote of 5 PinmemberMember 43208449-Feb-12 7:27 
GeneralRe: My vote of 5 PinmemberAyobami Adewole9-Feb-12 8:18 
QuestionD Pinmembercyrusholiday7-Feb-12 1:13 
AnswerRe: D PinmemberAyobami Adewole9-Feb-12 8:18 
QuestionAfter sending JPG header is broken? Pinmemberdescartes31-Jan-12 3:54 
QuestionWCF PinmemberGary Noter23-Jan-12 13:51 
AnswerRe: WCF PinmemberAyobami Adewole24-Jan-12 10:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.1411019.1 | Last Updated 2 Feb 2012
Article Copyright 2012 by Ayobami Adewole
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid