Learn step by step network programming using C#.Net socket, remoting, WCF and SignalR technology from lots of source code and description. All source code download link available at end of the blog post.
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.
Here file data is starting to
retrieve after file size and file name bytes. This has managed in 2ndline.
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
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:
SocketclientSock = 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.
Now I will discuss about, how we can transfer a large file (file size in GB) using Microsoft dot net socket programming using C# (C sharp) language. This code has written in Visual Studio 2005 (dot net 2).
To cover this article you need to read my few articles, these are –
1. Asynchronous Socket Server Programming for Beginner
2. Asynchronous Socket Client Programming for Beginner
3. File Transfer using C# Socket Programming
4. Split and Assemble large file (around 2GB) in C# dot net Programming
Steps
The basic code has covered in these article and that article basically comes by assembled these four. To transfer a large file from Client to Server I’ve followed these basic steps-
1)First read the file (slice wise) and store a slice data in a buffer (byte array). How a file can read slice wise, it has covered in my 4th article (Split and Assemble large file (around 2GB) in C#) in file split section. It’s required because TCP buffer is limited so if we try to send a large data then we will get TCP buffer overflow error.
2)Send these buffered data to server using TCP socket object. How it can be done, has covered in 3rd article (File Transfer using C# Socket programming). And for basic idea you can read article 1 & 2.
3)In server side when we starts to receive sliced data from client then we write these data in a file. How this can be done has covered in article 4 (Split and Assemble large file (around 2GB) in C#.net ), in file assemble section.
To receive file from Server to Client same process is applicable, just then server sends data by sliced and receive by Client in same way.
How to use DLL
In my code I have made these two functionality (server and client) in two separate class library (DLL file). By calling these two libraries (DLL file) any one can transfer data very easily. To do it need to follow these steps -
Step 1: Create Object
To use these dll to transfer data you need to create one client and one server object.
For client object -
SynchronusClient_ByteArr objClient = new SynchronusClient_ByteArr ("","localhost", @"C:\Documents and Settings\Administrator\UserData");
First argument for client id, if you keep it blank string then also ok, but when you use dll for multiple client (sender) to transfer multiple file to multiple client (receiver) then it’s mandatory. Otherwise file may goes to all user or different user. Next argument for server IP, and next for a temporary back up path, it’s require at file receive time from server.
Here and one more constructor with more argument there you can assign port no etc. Here default port is 8000 and 8001.
For Server object –
SyncSocketServerMulClient servObj = new SyncSocketServerMulClient();
If you use this code then server will load it’s default configuration, like port 8000 and 8001 and it’s default path to C: Other wise you can call overloaded method.
Step 2: Method & Properties
For server and client has some method which you need to call.
Client methods and properties are –
Picture 1 Picture 2
Picture 1 for Method and events of client object and Picture 2 for method and property of client class.
Hope from pic 1 you can understand everything very easily and from pic 2 also clear from it’s name. For ‘status’, it holds current status of client like, slicing data, sending data, receiving data etc and ‘progress’ it holds current % of data transfer currently done.
Server methods and properties are –
Picture 3 Picture 4
For pic 3 hope everything clear to you. But my comments here is, when you call start server then server starts and stays active as long as you call stop server. After call start server you can’t call it again before stop server call.
From pic 4 ‘bufferSize’ is for declare byte array length, you can define it as your self, ‘maxClientReceived’ for how many client can send or receive data at a time.
By using this code I’ve developed few large application, like text chat with smiles, file transfer, picture transfer, online drawing etc. Hope you will get a great experience by that code.
Download link
You can download source code from these two links-
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.IO;
/// That server code will run to access multiple client requrest and response. Here will not any
/// Un-zip and Decript technology. Server will save all data in Encripted-Zipped form which will
/// sent by Client.
public class SyncSocketServerMulClient
{
public static bool isServerRunning=false;
public static int receivePort,sendPort, maxClientReceived, bufferSize;
//public static int progress=0 ;
public string outPath ;
public static string status="",presentOperation = "";
public string currentStatus = "";
byte[] data = new byte[bufferSize];
//DATA FORMAT: [FILE SIZE LEN INFO[0-3]][FILE NAME LEN INFO[4-7]][FILE NAME DATA][FILE CONTENT]
//GET FILE NAME, SIZE ETC.
currentStatus =presentOperation = "Data Receiving";
int len = clientSock.Receive(data);
if (len == 0)
{
clientSock.Close();
return;
}
if (len == 3)
{
string clientData = Encoding.ASCII.GetString(data);
if (clientData.Substring(0, len) == "END")
return;
}
totalDataLen = BitConverter.ToInt32(data, 0);
fileNameLen = BitConverter.ToInt32(data, 4);
fileName = Encoding.ASCII.GetString(data, 8, fileNameLen);
fileContentStartIndex = 4 + 4 + fileNameLen;
receivedLen = len - fileContentStartIndex;
//READ DATA & STORE OF FIRST PACKET
//DELETE IF FILE ALREADY EXIST
if (File.Exists(outPath + fileName))
File.Delete(outPath + fileName);
bWriter = new BinaryWriter(File.Open(outPath + fileName, FileMode.Append));
bWriter.Write(data, 0, len);
while (true)
{
if (receivedLen < len =" clientSock.Receive(data);" currentstatus ="presentOperation" currentstatus =" presentOperation" clientinfodata =" new" clientinfodata =" Encoding.ASCII.GetBytes(" status = "Access Denied by server end." status = "Address Already In Use." status = "Address Not Available." status = "Connection aborted by server." status = "Connection refused by server." status = "Connection Reset." status = "Destination Address Required." status = "Disconnecting." status = "Target Host is Down." status = "Target Host Not Found." status = "Target Host Unreachable." status = "In Progress." status = "Interrupted." status = "Invalid Argument." status = "Network Down." status = "Network Reset." status = "Network Unreachable." status = "No Buffer Space Available." status = "No Data." status = "Not Connected." status = "Not Initialized." status = "Not Socket." status = "Operation Aborted." status = "Socket already Shutdown." status = "Too Many Open Sockets." status = "Too Many Open Sockets." status = "Have some unknown problem in Socket." isserverrunning =" true;" threadsendserver =" new" ipendsend =" new" sendsock =" new" isserverrunning =" true;" clientsock =" sendSock.Accept();" serobj =" new" newclient =" new" clientsocket="(Socket)clientObject;" filenamewithpath = "" breader =" null;" status = "" clientdata =" new" clientdatalen =" clientSocket.Receive(clientData);" clientdatalen ="=" clientdatalen ="=" clientdatastr =" Encoding.ASCII.GetString(clientData);" clientidlen =" BitConverter.ToInt32(clientData," filenamelen=" BitConverter.ToInt32(clientData," clientid =" Encoding.ASCII.GetString(clientData," filename =" Encoding.ASCII.GetString(clientData," copiedfilename =" clientId" filenamewithpath =" this.outPath;" filenamewithpath =" fileNameWithPath.Replace(" length ="=" currentstatus =" presentOperation" breader =" new" data =" new" sentdatasize =" (int)bReader.BaseStream.Length;" data =" new" sentdatasize =" bufferSize;" totalsentdataslot =" 1;" totaldatasize =" (int)bReader.BaseStream.Length;" progress =" (int)(((float)sentDataSize" progress =" (int)(((float)sentDataSize" enddata =" new" sentdatasize =" (int)bReader.BaseStream.Length;" progress =" (int)(((float)sentDataSize" currentstatus =" presentOperation" strfleerr = "ERROR" tempfleerrarr =" Encoding.ASCII.GetBytes(strFleErr);" currentstatus =" presentOperation" status = "Access Denied by server end." status = "Address Already In Use." status = "Address Not Available." status = "Connection aborted by server." status = "Connection refused by server." status = "Connection Reset." status = "Destination Address Required." status = "Disconnecting." status = "Target Host is Down." status = "Target Host Not Found." status = "Target Host Unreachable." status = "In Progress." status = "Interrupted." status = "Invalid Argument." status = "Network Down." status = "Network Reset." status = "Network Unreachable." status = "No Buffer Space Available." status = "No Data." status = "Not Connected." status = "Not Initialized." status = "Not Socket." status = "Operation Aborted." status = "Socket already Shutdown." status = "Too Many Open Sockets." status = "Too Many Open Sockets." status = "Have some unknown problem in Socket." status =" ex.Message;" isserverrunning =" false;" ipaddress =" Dns.GetHostAddresses(" ipend =" new" clientsock =" new" strdata = "END" clientdata =" new" clientdata =" Encoding.ASCII.GetBytes(strData);" serverdata =" new" len =" clientSock.Receive(serverData);" style="font-weight: bold; color: rgb(51, 51, 255);" size="4">Client Code is here:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
/// Client open a syncronous socket and send file to server, here asynchronous mode becomes by
/// Threading, and here uses Byte Array to transfer data.
public class SynchronusClient_ByteArr
{
public delegate void FileSendCompletedDelegate();
public event FileSendCompletedDelegate FileSendCompleted, FileReceiveCompleted;
public static int progress = 0, portSend, portReceive;
int bufferSize;
public static string status = "", presentOperation = "", ipAddress, outPathDefault = "";
private static string outPathUserSelected = "";
string clientId = "";
string fileNameWithPath;
public static bool isSaveToDefaultPath = false;
static int totalSentDataSlot;
//NEW FILE NAME IS NOW IN IT'S OWN EXTENSION NEED TO CHANGE .sjb FORM
//Only file name
int k = newFileName.Length - 1;
while (newFileName.Substring(k, 1) != ".")
{
k--;
}
newFileName = newFileName.Substring(0, k);
newFileName = newFileName + ".sjb";
this.fileNameWithPath = filePath + tempFileName;// this.fileNameWithPath;
presentOperation = "Data Sending";
IPAddress[] serverIp = Dns.GetHostAddresses(SynchronusClient_ByteArr.ipAddress);
IPEndPoint ipEnd = new IPEndPoint(serverIp[0], SynchronusClient_ByteArr.portSend);
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
server.Connect(ipEnd);
int sentDataSize;
byte[] data;// = new byte[bufferSize];
bReader = new BinaryReader(File.Open(fileNameWithPath, FileMode.Open));
if (bReader.BaseStream.Length <= bufferSize) { data = new byte[bReader.BaseStream.Length]; bReader.Read(data, 0, (int)bReader.BaseStream.Length); sentDataSize = (int)bReader.BaseStream.Length; } else { data = new byte[bufferSize]; bReader.Read(data, 0, bufferSize); sentDataSize = bufferSize; } string onlyFileName; fileNameWithPath = fileNameWithPath.Replace("\\", "/"); onlyFileName = fileNameWithPath; while (onlyFileName.IndexOf("/") != -1) onlyFileName = onlyFileName.Substring(onlyFileName.IndexOf("/") + 1); //DATA FORMAT: [FILE SIZE LEN INFO[0-3]][FILE NAME LEN INFO[4-7]][FILE NAME DATA][FILE CONTENT] byte[] dataLenBytes = BitConverter.GetBytes((int)bReader.BaseStream.Length); byte[] fileNameLenBytes = BitConverter.GetBytes(onlyFileName.Length); byte[] fileNameBytes = Encoding.ASCII.GetBytes(onlyFileName); byte[] allData = new byte[8 + fileNameBytes.Length + data.Length]; //MAKE FIRST PACKET TO SERVER WITH FILE SIZE & FILE NAME dataLenBytes.CopyTo(allData, 0); fileNameLenBytes.CopyTo(allData, 4); fileNameBytes.CopyTo(allData, 8); data.CopyTo(allData, 8 + fileNameBytes.Length); //SEND FIRST PACKET TO SERVER server.Send(allData); totalSentDataSlot = 1; int totalDataSize = (int)bReader.BaseStream.Length; progress = (int)(((float)sentDataSize / totalDataSize) * 100); while (sentDataSize < progress =" (int)(((float)sentDataSize" enddata =" new" sentdatasize =" (int)bReader.BaseStream.Length;" progress =" (int)(((float)sentDataSize" receivedata =" new" recvlen =" server.Receive(receiveData);" presentoperation = "Data Sending Completed" status = "Access Denied by server end." status = "Address Already In Use." status = "Address Not Available." status = "Connection aborted by server." status = "Connection refused by server." status = "Connection Reset." status = "Destination Address Required." status = "Disconnecting." status = "Target Host is Down." status = "Target Host Not Found." status = "Target Host Unreachable." status = "In Progress." status = "Interrupted." status = "Invalid Argument." status = "Network Down." status = "Network Reset." status = "Network Unreachable." status = "No Buffer Space Available." status = "No Data." status = "Not Connected." status = "Not Initialized." status = "Not Socket." status = "Operation Aborted." status = "Socket already Shutdown." status = "Too Many Open Sockets." status = "Too Many Open Sockets." status = "Have some unknown problem in Socket." status =" ex.Message;" fbd =" new" outpathuserselected =" fbd.SelectedPath;" startfilereceivethread =" new" outpathuserselected =" ReceivePath;" startfilereceivethread =" new" server =" null;" bwriter =" null;" rcvfilename = "" filename = "" status = "" onlyfilename =" onlyFileNameObj.ToString();" presentoperation = "Data Compressing" length ="=" clientid =" DateTime.Now.Ticks.ToString();" clientidlenbytes =" BitConverter.GetBytes(clientId.Length);" clientidbytes =" Encoding.ASCII.GetBytes(clientId);" filenamelenbytes =" BitConverter.GetBytes(onlyFileName.Length);" filenamebytes =" Encoding.ASCII.GetBytes(onlyFileName);" alldata =" new" presentoperation = "Data Sending" serverip =" Dns.GetHostAddresses(SynchronusClient_ByteArr.ipAddress);" ipend =" new" server =" new" status = "" progress =" 0;" presentoperation = "" server =" (Socket)clientObject;" flag =" true;" data =" new" presentoperation = "Data Receiving" len =" server.Receive(data);" len ="=" strtemp =" Encoding.ASCII.GetString(data," strtemp ="=" status = "File yet not sent by Sender" presentoperation = "Data Receiving Not Started" progress =" 0;" totaldatalen =" BitConverter.ToInt32(data," filenamelen =" BitConverter.ToInt32(data," filename =" Encoding.ASCII.GetString(data," filecontentstartindex =" 4" receivedlen =" len;//" outpathdefault =" outPathDefault.Replace(" outpathuserselected =" outPathUserSelected.Replace(" fbd =" new" bwriter =" new" bwriter =" new" bwriter =" new" progress =" (int)(((float)receivedLen" len =" server.Receive(data);" val =" (float)receivedLen" progress =" (int)(((float)receivedLen" presentoperation = "Data Decompressing" rcvfilename =" ZipUnzip.LZO_Algorithm.LZO.Decompress(outPathDefault" rcvfilename =" ZipUnzip.LZO_Algorithm.LZO.Decompress(outPathUserSelected" orgfilename =" rcvFileName=" orgfilename =" orgFileName.Substring(orgFileName.IndexOf(" isserverrunning =" false;" presentoperation = "Data Receiving Completed" progress =" 100;" status = "Access Denied by server end." status = "Address Already In Use." status = "Address Not Available." status = "Connection aborted by server." status = "Connection refused by server." status = "Connection Reset." status = "Destination Address Required." status = "Disconnecting." status = "Target Host is Down." status = "Target Host Not Found." status = "Target Host Unreachable." status = "In Progress." status = "Interrupted." status = "Invalid Argument." status = "Network Down." status = "Network Reset." status = "Network Unreachable." status = "No Buffer Space Available." status = "No Data." status = "Not Connected." status = "Not Initialized." status = "Not Socket." status = "Operation Aborted." status = "Socket already Shutdown." status = "Too Many Open Sockets." status = "Too Many Open Sockets." status = "Have some unknown problem in Socket." status =" ex.Message;" style="">
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 :-).
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)
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
Now starts for Client part of socket application. Now I will show a simple client socket with an example: You have to follow just few steps these are: I. Create a Ip address object with Server Ip using Dns. IPAddress []ipAddress= Dns.GetHostAddresses("localhost");
II. Again built an IPEndPoint with that IPAddress with same port of server. IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], 5656);
III. Now creates a socket object with three parameter like code. Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
IV. Now create a byte array to send data to server. V. Finally send that byte array to server. clientSock.Send(clientData);
VI. To receive data from server just wait socket using Receive function, when some data received by client socket then it fill a byte array and return a interger value received bytes length. int len = clientSock.Receive(serverData);
VII. Now close the client socket.
The complete client code is giving below:
using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets;
namespace Client_Socket { class Program { static void Main(string[] args) { 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);
string strData = "Message from client end."; byte[] clientData = new byte[1024]; clientData = Encoding.ASCII.GetBytes(strData); clientSock.Send(clientData);
byte[] serverData = new byte[1024]; int len = clientSock.Receive(serverData); Console.WriteLine(Encoding.ASCII.GetString(serverData,0,len)); clientSock.Close();