Saturday, October 20, 2012

Send File from Server to Client using C# Socket Programming


Hello Friends, after long day’s gap I am writing some blog for you. During this time many things has changed in technological world like earlier I write code with VS 2008 and now VS 2012 has released. Also lots of changes in our life too. I believe this time I can write my blog with better English than earlier, which will help you to read this. Ok lets read this post about to learn new thing which is about to send small file from server to client. This is just opposite of sending file from client to server. This is the basic of large file transfer, later I shall use the same thing to send large file from server to client and finally will use both (client to server and server to client) large file transfer code client to client. I shall come to that point step by step.

To send file from server to client need to follow below steps as describe in table by client and server:


  File Transfer from Server to Client
Server
Client
1. Server creates an IP End Point and a socket object then bind socket object with IP end point and sends it to listen mode for incoming client request.





4. Server receive client request and accept it. Once connection established, server create another socket object which will handle this client all requests until connection ends. Client will be informed internally by TCP about connect success.




6. Prepare byte data from file which will be sent to client.

7. Server starts sending byte data over connected socket.











12. Once data transfer complete and client closes socket connection, server also close server socket object.
13. Server program work ends here.



2. Client creates an IP End Point and a socket object.

3. Try to connect to server using client socket by help of IP end point.







5. Start preparations to store incoming byte data from server.






8. Client receives file byte data along with file name and stores it in byte array.

9. Client retrieve file name from byte data.

10. Client opens a binary stream writer with file name to store byte data in it. 

11. Once file save complete client closes binary stream writer and server socket objects.






14. Client program work ends here.
 


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.


So 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 (same thing has applied in 2GB file transfer article) and need to send one by one slice. So there will be loop to send file from server to client that means step 5 to step 7 will repeat.


Also server can send some particular file based on client request. But for that client need to send file name at the time of server request. So server can search file based on this information, so can read and send particular file to client.


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. I am planning to write codes up to multiple client to client large file transfer with the help of one server application step by step. So keep watching my blog to learn new things.


Download this project from below link:


Full codes are here...

Client code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace Client_Socket
{
//FILE TRANSFER USING C#.NET SOCKET - CLIENT
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("That program can transfer small file. I've test up to 850kb file");
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);


byte[] clientData = new byte[1024 * 5000];
string receivedPath = "C:/";

int receivedBytesLen = clientSock.Receive(clientData);

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

Console.WriteLine("Client:{0} connected & File {1} started received.", clientSock.RemoteEndPoint, fileName);

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

Console.WriteLine("File: {0} received & saved at path: {1}", fileName, receivedPath);

bWrite.Close();
clientSock.Close();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("File Sending fail." + ex.Message);
}

}
}
}


Server codes are here...



Server code:


using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace beginSocketServer
{
//FILE TRANSFER USING C#.NET SOCKET - SERVER
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("That program can transfer small file. I've test up to 850kb file");
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
sock.Listen(100);
//clientSock is the socket object of client, so we can use it now to transfer data to client
Socket clientSock = sock.Accept();


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);


clientSock.Send(clientData);
Console.WriteLine("File:{0} has been sent.", fileName);


clientSock.Close();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("File Receiving fail." + ex.Message);
}
}
}
}

Send File from Server to Client using C# Socket Programming 6/6



Server codes are here...



Server code:


using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace beginSocketServer
{
//FILE TRANSFER USING C#.NET SOCKET - SERVER
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("That program can transfer small file. I've test up to 850kb file");
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 5656);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
sock.Listen(100);
//clientSock is the socket object of client, so we can use it now to transfer data to client
Socket clientSock = sock.Accept();


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);


clientSock.Send(clientData);
Console.WriteLine("File:{0} has been sent.", fileName);


clientSock.Close();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("File Receiving fail." + ex.Message);
}
}
}
}

Send File from Server to Client using C# Socket Programming 5/6



Full codes are here...

Client code:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace Client_Socket
{
//FILE TRANSFER USING C#.NET SOCKET - CLIENT
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("That program can transfer small file. I've test up to 850kb file");
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);


byte[] clientData = new byte[1024 * 5000];
string receivedPath = "C:/";

int receivedBytesLen = clientSock.Receive(clientData);

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

Console.WriteLine("Client:{0} connected & File {1} started received.", clientSock.RemoteEndPoint, fileName);

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

Console.WriteLine("File: {0} received & saved at path: {1}", fileName, receivedPath);

bWrite.Close();
clientSock.Close();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("File Sending fail." + ex.Message);
}

}
}
}



Send File from Server to Client using C# Socket Programming 4/6



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.


So 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 (same thing has applied in 2GB file transfer article) and need to send one by one slice. So there will be loop to send file from server to client that means step 5 to step 7 will repeat.


Also server can send some particular file based on client request. But for that client need to send file name at the time of server request. So server can search file based on this information, so can read and send particular file to client.


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. I am planning to write codes up to multiple client to client large file transfer with the help of one server application step by step. So keep watching my blog to learn new things.


Download this project from below link:

https://rapidshare.com/files/691859425/Client and Server - Send Small File from Server to Client.zip