Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Small File Transfer from Server to Client

0.00/5 (No votes)
5 Mar 2013 1  
This small application will help you to gain basic knowledge about how file can be sent from server to client.

Introduction

This small application will help you to gain basic knowledge about how file can be sent from server to client.

Background

Earlier I have posted article about how to transfer file from client to server and now going to post file transfer server to client. So by adding these two you can write code about to transfer file client to client.

The complete series about to learn socket programming is available in my blog Socket Programming in C# . You can visit there for more articles on socket and distributed architecture programming using C#. 

Earlier I have seen users are getting problem for my poor English, now trying to improve this part. I believe now you will not get much problem for my English. 

Using the Code

To send file from server to client there must be two applications that is Server application and client application. In code I have mentioned these two parts individually. In below section I am describing Server action means server application is working and you need to check server code, for client action need to check client code. Handshaking of these two socket programming applications should be following:

1) Server Action: First need to run server application, this server application will open an endpoint with predefined IP address and port number and will remain in listen mode to accept new socket connection request from client. 

It’s just like some one is waiting at some fixed position to reply on some ones request. 

This below section of code from server application is doing exactly same thing:

IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
sock.Listen(100);

Here line no 1 is creating an ipEnd point with port number 5656 and IP is local machine IP address. Port number can be anything except well known port number (port number should be more than 1024).

Next two lines are creating a socket object and binding with previously created IPEnd point.

Last line is sending newly created socket object to listen mode to accept new connection request from client.

So you need to run server application first and then client application.

2) Client Action: Now turn is coming to client to request server.

IPAddress[] ipAddress = Dns.GetHostAddresses("localhost");
IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], 5656);
Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
clientSock.Connect(ipEnd);

These codes are from client application, here first two lines are using to get Localhost IP address and by using this creating new IPEnd point. Be sure there IP address and port number must be same as server address. I am running my applications in same machine so using localhost.

Next two lines of code is creating a socket object and trying to connect by using IPEnd point. So this socket object will try to connect server socket which was in listen mode.

3) Server Action: Again turn comes to server about to response on client’s request and this is doing by below line of code in server application: 

Socket clientSock = sock.Accept(); 

This "sock" is server socket object which was created previously and it was in listen mode. This sock object will accept client request and generate a new socket object with name "clientSock". Rest all work in server side will be performed by "clientSock" object to handle this particular client request.

4) Server Action: These codes are not directly related with socket programming. This is using to read and send file to client. 

string fileName = "test.txt";// "Your File Name"; 
string filePath = @"C:\FT\";//Your File Path;
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
byte[] fileData = File.ReadAllBytes(filePath + fileName);
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); 

These lines of code reading some particular file from local drive and string its data in byte array "clientData". File data need to store in array with raw byte format to send these to client. With data file name size string at initial of file data. This is predefined between client and server and it needs to do, otherwise client will not get file name which is sending by server.

For my case I am using first four byte to represent file name length and form 5th byte file name is storing. So all file data will store after file name.

5) Server Action: Now file data is in byte array and it needs to send to client. The same thing is happening by using below code with the help of client socket (clientSock) object, which was created during client request acceptance.

clientSock.Send(clientData); 

Basically server application task ends here for small file transfer. Remaining code has used for some decoration and socket closing related things.

5) Client Action: Now again turn comes to client and it will perform below tasks:

byte[] clientData = new byte[1024 * 5000];
string receivedPath = "C:/";
int receivedBytesLen = clientSock.Receive(clientData);

Here first two lines are just creating byte array to store server data and path is used to decide where data to be save. In my code, I am saving data in C: drive.

Last line is start receiving data from server. Whenever client socket starts receiving server data then it returns length of data which has captured in a integer variable.

6) Client Action: This section of code is retrieving file name length and by using this file name which was sent by server at the starting of file data. This will require retrieving file name.

int fileNameLen = BitConverter.ToInt32(clientData, 0); 
string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);

7) Client Action: Now received data is saving at client side by using below lines of code with the help of binary stream writer.

BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath + fileName, FileMode.Append)); 
bWrite.Write(clientData, 4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);

Here file data is starting to retrieve after file size and file name bytes. This has managed in 2nd line.

By that way one small file can be sent from server to client. 

8) Client and Server Action: Now server and client both will do same activity; that is to release server and client socket by using close method of socket. Client needs to close binary stream writer as well.

bWrite.Close(); 
clientSock.Close(); 

Points of Interest  

By following these steps a file can be sent from server to client. Same way we can send large file from server to client. TCP buffer can not handle large data size at a time. So if you try to send large file it will throw overflow error. To avoid this error you need to slice big file in small pieces and need to send one by one piece. So there will be loop to send file from server to client that means step 5 to step 7 will repeat.

Server can send some particular file based on client request. But for that client need to send requested file information at the time of server request. Server can search file based on client request.

By handling multiple clients objects one server can send file to multiple clients simultaneously but for that you need to create multithread application and need to keep track client socket object array with data file. So programming must be more complex but basic thing is same.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here