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
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 - CLIENTclass 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 - SERVERclass 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 clientSocket 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);}}}}