Thursday, November 22, 2007

File Transfer using C# .Net Socket Programming



File transfer using C# socket is Client-Server combined process and quite complex too. This process we can divide in three phases.
  1. Preparation stage for Server and Client.
  2. Establish communication channel to send-receive data between Client and Server.
  3. Break the communication channel and release all resources.
To complete data transfer from client to server need to follow below steps as describe in table. Later discussing about each steps but before that go trough the logic which I am going to follow. 



File Transfer from Client to Server
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.








5. 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. Start preparations to store incoming byte data from client.



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

9. Server retrieve file name from byte data.

10. Server opens a binary stream writer with file name to store byte data in it. 
 
11. Once file save complete server closes binary stream writer and server socket objects.




14 Server program ends here.



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

3. Prepare byte data from file which will be sent to server.

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









7. Client starts sending byte data over connected socket.











12. Once data transfer complete and server closes socket connection, client also close client socket object.

13. Client program work ends here.
 

Phase 1, Preparation: In that phase server and client both prepared to send some data.
At Server: Server makes an object of IPEndPoint class with some Port number with some IP address. Then creates a socket object with Internetwork family with protocol type IP(or IDP or else) to transfer Stream type data. At last bind this socket objects with that IPEndPoint object and place socket in listen mode to accept client request.
At Client: Client makes another IPEndPoint object with Server IP address and same port number. Then creates a socket object as same as Server socket object in same way. After completing these client reads a file and stores bytes data in a byte array object.
Phase 2, Establish communication and transfer data: Now client socket tries to connect to server socket which was in listen mode. When server socket get requests from client then it accept request and established connection between server and client by producing a new socket object. Next data transmission operation continues by that new socket object.
When new client socket request accepted by server and connection established then client send byte data by “socket-object. Send()” method to server and at server end these data received by “socket-object. Receive()” method. When data successfully received at server end, server saves these bytes in a file using byte data stream.
For large file, “these data read at client -send to server-receive at server end - save received data at server end” these steps are perform repeatedly until client reach at EOF (End Of File). But in this program only small file covered for this no need of looping, for this type of example read my “Send 2GB file using TCP socket programming” article.


Phase 3, Break communication channel and release resources: When last slice of byte data saved at server, client and server close the socket object and release all resource like file stream, socket object etc.

By that way a file transferred from client to server. But there has no way to call a client from server and send file. My example describe how to send file from client to server but can you imagine how opposite done? Yes if you able learn client to server data transfer properly then it is very easy. Try your self first, if failed then try it again and continue at least three times, then you will able to do it. But….but again failed then ask me I will help you about it :-).

For code url is:
Client Code:

[C#]

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


string fileName = "Your File Name";
string filePath = "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.Connect(ipEnd);
clientSock.Send(clientData);
Console.WriteLine("File:{0} has been sent.", fileName);
clientSock.Close();
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("File Sending fail." + ex.Message);
}

}
}
}
[Visual Basic]

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Namespace Client_Socket
'FILE TRANSFER USING C#.NET SOCKET PROGRAMMING- CLIENT
Class Program
Private Shared Sub Main(ByVal args As String())
Try
Console.WriteLine("That program can transfer small file. I've test up to 850kb file")
Dim ipAddress As IPAddress() = Dns.GetHostAddresses("localhost")
Dim ipEnd As New IPEndPoint(ipAddress(0), 5656)
Dim clientSock As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)
Dim fileName As String = "Your File Name"
Dim filePath As String = "Your File Path"
Dim fileNameByte As Byte() = Encoding.ASCII.GetBytes(fileName)
Dim fileData As Byte() = File.ReadAllBytes(filePath + fileName)
Dim clientData As Byte() = New Byte(4 + fileNameByte.Length + (fileData.Length - 1)) {}
Dim fileNameLen As Byte() = BitConverter.GetBytes(fileNameByte.Length)
fileNameLen.CopyTo(clientData, 0)
fileNameByte.CopyTo(clientData, 4)
fileData.CopyTo(clientData, 4 + fileNameByte.Length)
clientSock.Connect(ipEnd)
clientSock.Send(clientData)
Console.WriteLine("File:{0} has been sent.", fileName)
clientSock.Close()
Console.ReadLine()
Catch ex As Exception
Console.WriteLine("File Sending fail." & ex.Message)
End Try
End Sub
End Class
End Namespace

Continued code...
Server Code:
[C#]

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 PROGRAMMING - 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);
Socket clientSock = sock.Accept();

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

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 Receiving fail." + ex.Message);
}
}
}
}

[Visual Basic]

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Namespace beginSocketServer
'FILE TRANSFER USING C#.NET SOCKET PROGRAMMING- SERVER
Class Program
Private Shared Sub Main(ByVal args As String())
Try
Console.WriteLine("That program can transfer small file. I've test up to 850kb file")
Dim ipEnd As New IPEndPoint(IPAddress.Any, 5656)
Dim sock As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP)
sock.Bind(ipEnd)
sock.Listen(100)
Dim clientSock As Socket = sock.Accept()

Dim clientData As Byte() = New Byte(1024 5000 - 1) {}
Dim receivedPath As String = "e:/"

Dim receivedBytesLen As Integer = clientSock.Receive(clientData)

Dim fileNameLen As Integer = BitConverter.ToInt32(clientData, 0)
Dim fileName As String = Encoding.ASCII.GetString(clientData, 4, fileNameLen)

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

Dim bWrite As 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 ex As Exception
Console.WriteLine("File Receiving fail." & ex.Message)
End Try
End Sub
End Class
End Namespace

41 comments:

vaibhav said...

nice 1

Michael said...

Thank you for this.

Pratiksha said...

How to transfer large files....5 mb or more


Thanks
Pratiksha

ေသာ ၾကာ သူ ရ said...

Nice code, there is one thing i want to know, How can i send response message and files from server to client and how can client receive them?
Thant
proteus

SHINOJ said...

how to send emotions through sockets as bytes?and convert to image plz send reply

Chua said...

Thanks for answering my emailed queries earlier.

However, I have another problem. I converted your client over to .NET Compact Framework compatable, because I'm trying it through a Windows Mobile 6.
I just changed your

byte[] fileData = File.ReadAllBytes(filePath + fileName);

to

public static byte[] ReadAllBytes(string path){ byte[] buffer; using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { int offset = 0; int count = (int)fs.Length; buffer = new byte[count]; while (count > 0) { int bytesRead = fs.Read(buffer, offset, count); offset += bytesRead; count -= bytesRead; } } return buffer;}

because .NET Compact Framework doesn't support File.ReadAllBytes I guess. It should work the same.

However, my problem here is that it feels as if there is only 1 transmission. The actual file size is 74.3KB only, but the 1st few parts were allowed to be sent over.

Do you have any recommendations for this? Sorry, would also like to ask whether only 1 time transmission is catered for it only?

Thank you!

akki said...

Its is seriously a simple and tidy code....but as i am new in socket programming i am not able to transfer files of large size....so, could u plz let me know how to transfer file of around 25MB size? Thanks in advance :)

Cheers,
Prashant

Pat said...

Hi,
Thanks for these great examples. I am tring to create Asynchronous File Transfer Client / Server applications. Using the MS code I can get the Asynchronous examples working however now I'm tring to modify this code to send files instead of strings. It seems examples of this are hard to come by on the web. Do you have any code examples that might help me? Thank you.

ashish said...

I am having exception as
"Socket closed du to Dead Network"
want help

Ege Ilıcak said...

thank you for the example. But I want to know that how can we transfer large files? Can you give an example?

Thanks. Ege.

Mariam said...

Hey I am new to this ,can u plz tell me how to send videos from one computer to another (sending the videos frame by frame)

Mariam said...

hey i am new to this can u plz tell me which of the two(i.e. UDP and TCP)to use when i want to tranfers videos frame by frame from one computer to another and also how do i do it?

Suman Biswas said...

Hi Mariam,
You can use UDP to transfer video data, also for voice UDP is applicable.

Thanks
Suman

John Blesswin said...

thanks for this da..
its nice

but i want to transfer large files.

Mariam said...

thanks suman,
but i need guidance as to how am i supposed to go about it i m totally clue less.
Can any of u guyz plz guide me as to how i should proceed?

Ege Ilıcak said...

Here is an example of how to transfer large files:

Client Side:
http://codetechnic.blogspot.com/2009/02/sending-large-files-over-tcpip.html

Server Side:
http://codetechnic.blogspot.com/2009/02/receiving-large-files-over-tcpip-in-c.html

John Blesswin said...

Thank u 4 this program .i try it . it work nice fully..

and one more program i need socket program send audio files in java language..

plz send its urgent ...
tc
bye

Suman Biswas said...

Sorry I don't write code in Java.

Suman

Aljaz said...

Hi! I have made file transfer from client to server map to work. Now i don't know how to make it opposite, to transfer from server to client. If anyone could help me, plz let me know. My email is: aljazstraser@gmail.com

geet said...

i run this project it runs successfully but when i enter file name and path in client application and press enter then it is showing me error "No connection could be made because the target machine actively refused it"

Can any1 help me?

Suman Biswas said...

Hi Geet,
Your Server is not running or your client's server address/port is not correct, so it can not connect to server. So you are getting this error.

Suman

geet said...

i am running this on my computer so my client and server is both my computer (localhost)
then how can it be wrong?

Suman Biswas said...

Hi Geet,
First run your server application then start client application.
When you are trying to run client then plz check is it connecting to 'localhost' / 127.0.0.1 and use same port for server and client. You must be sure about this otherwise you will get same problem.

This message comes from system only when client unable to find server.

Thanks,
Suman

geet said...

i am not changing anything in the program written above
If that is right then error should not be generated.

Suman Biswas said...

Hi Geet,
This is working fine...I have tested once again.

Please check about your testing procedure.

Run Server then Client.

By the way, in client have you change the source file name and path?

Thanks,
Suman

Suman Biswas said...

These two lines in client...

string fileName = "PNR .txt";
string filePath = @"C:\";

Suman Biswas said...

These two lines in client...

string fileName = "PNR .txt";
string filePath = @"C:\";

geet said...

it works thannx SUMAN

dyyyy said...

hii thank you for this
just wanted to ask, does this work between a PDA and a server, using windows mobile 6?

Kalyani said...

what following line indicates ?This line is in server code.If i want to tranfer large file i have to change this factor or not?

byte[] clientData = new byte[1024 * 5000];

Suman Biswas said...

Hi,
When data received at Server then it stores in a array, so this is using for that. Here at server receives 5KB data at one time. See at client it sends 5KB of data. You can not send much data due to TCP buffer.

This article for basic file transfer. If you understand it well then read then read the article how a file can split and assemble. After that read send large file article. Every thing you will understand.

Suman

Neduet said...

both the client and server programs compiling without any error..thanks for that
but my client doesnt pick the file i need to trasfer.it gives me an error saying file not found
please help

Rashmi said...

hi its grt one..
but m gettin d error

An address incompatible with the requested protocol was used[1::5656]

wat to do??

al said...

Hi suman,

i used ur code in local system both server and client on same machine..i got it worked fine..But now my task is to download a file present in a particular folder in live server...Actually as per ur code there are two diff programs for client and server..But according to my task i need to write both the code on client machine(i.e,connecting to server,connecting to client and download the file...no code must be written on server system)..I clubbed your code into a single program...but wen i run the code i'm getting this error...'A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond...'....can u please help me out...is this the correct way of coding...

Suman Biswas said...

I think your process is not right, if client tries to connect to server and if you donot keep server port open in server then how client can communicate to server?

Two application must be there one will open connection and another will connect, based on that data will be transfer between two computer. This is basic concept of socket programming. :)
Suman

al said...

Hi Biswas,

Thanks for ur response..You said that the two applications are must..But can i write the two applications on client system..(One appl coding with serverIP and another with client IP)..Else i send my program so that u can give me some idea...But no code must be written on server system...all the coding to access data must be done in client system

haries said...

nice one, but i have make a program using your code here... the server is able to:
Server have function like this:

1. listening incoming connection
2. send message to client (chatting application)
3. send broadcast messages to clients
4. kill process at client
5. retrive list drive,file and folder on the specific client
6. upload and download file larger than 2 gigabyte (send and receive file to/from client), can send single file or multiple file (if you send folder and in the folder have subfolder and alot file in it, you dont need to create prototype like creating list file recursively... the library will handle it for you)
7. screen capture from desktop screen client
8. much more

Client have function like this:

1. request connection
2. send message to server
3. send message to other client
4. much more

You can view it here
http://classlibrary.blogspot.com/2012/03/how-using-class-library-for-making.html

Thanks for your usefull code, see ya...

135cc said...

i have a problem. I have successfully sent file from client to server. NOW i would like to sent list of those file to the client which client has sent . To do this I made another socket at server side to send list to client. and made another socket to accept lists. BUT One error is continuously giving headache to me "connection was made on already connected socket". I have closed previous socket also. BUT still i am getting same error.. CAN you plz help me.

Suman Biswas said...

Hi 135cc,
why only 135cc and not 180cc/350cc or more???...definitely its Pulsar type bike. :D

Solution depends on your coding pattern. Can you send this data by same socket, that means only one socket will be used for both?
If not possible then first disconnect and close the socket and dispose it forcefully. Then try another socket.
Be sure that no thread is accessing the earlier socket object, if it is in used by any thread then you can not close or dispose it and will get similar error.

Try and let me know.

Regards
Suman

Bill said...
This comment has been removed by the author.
Adnan Arshad said...

Dear Please send me the code in which server echo back the image file shared to it.