Friday, October 23, 2009
User to user file transfer using C# .Net Remoting technology
I will discuss later, for now just the codes…
Remoting / Common base code is here:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Collections;
namespace RemoteBase
{
///
/// Sample object to demonstrate the use of .NET Remoting.
///
public class SampleObject : MarshalByRefObject
{
ArrayList alOnlineUser = new ArrayList();
Hashtable htUserData = new Hashtable();
Hashtable htFileData = new Hashtable();
private int key = 0;
private string receiverID,senderID,fileName,fileTransferStatus;
private int fileSize;
private bool isFileTransferring = false;
#region USER JOINING AND ONLINE USER RELATED
public bool JoinToChatRoom(string name)
{
if (alOnlineUser.IndexOf(name) > -1)
return false;
else
{
alOnlineUser.Add(name);
return true;
}
}
public void LeaveChatRoom(string name)
{
alOnlineUser.Remove(name);
}
public ArrayList GetOnlineUser()
{
return alOnlineUser;
}
public int CurrentKeyNo()
{
return key;
}
#endregion
#region FILE INFORMATION ACCESS BETWEEN SENDER AND RECEIVER
public bool SetFileInfo(string senderId, string receiverId, string fileName, int fileSize)
{
if (!this.isFileTransferring)
{
lock (this)
{
this.isFileTransferring = true;
}
this.senderID = senderId;
this.receiverID = receiverId;
this.fileName = fileName;
this.fileSize = fileSize;
return true;
}
else//Now some file transferring, so need to wait
return false;
}
public string GetFileName_Size_SenderId(string receiverId)
{
if (this.receiverID == receiverId)
return this.fileName + ":" + this.fileSize.ToString() + ":" + this.senderID;
else
return null;
}
#endregion
#region FILE TRANSFER BETWEEN SENDER AND RECEIVER
///
/// This method is used to receive data from sender and hold in a array to deliver receiver.
///
///
///
///
///
public bool SendDataToServer(byte[] data, int dataSliceNo, string senderId)
{
lock (this)
{
htFileData.Add(receiverID + dataSliceNo.ToString(), data);//Key= receiverId + sliceNo, binary data
}
return true;
}
// This method is used to receive data from server to receiver.
public byte[] GetDataFromServer(string receiverId, int nextSliceNo)
{
if (htFileData.Contains(receiverID + nextSliceNo.ToString()))
{
lock (this)
{
byte[] tempByteData = (byte[])htFileData[receiverID + nextSliceNo.ToString()];
htFileData.Remove(receiverID + nextSliceNo.ToString());//Key= receiverId + sliceNo
return tempByteData;
}
}
else
return null;
}
///
/// This method is used to declare that file has succesfully received by the receiver. It invokes after the whole file
/// received by the receiver.
///
///
public void ReceiveFileConfirm(string clientID)
{
if (clientID == receiverID)
{
this.fileTransferStatus = "File transfered successfully by " + this.receiverID;
this.receiverID = "";
lock (this)
{
this.isFileTransferring = false;
htFileData.Clear();
}
}
}
public void RejectFile(string clientID)
{
if (this.receiverID == clientID)
{
this.fileTransferStatus = "File has rejected by " + this.receiverID;
this.receiverID = "";
lock (this)
{
this.isFileTransferring = false;
htFileData.Clear();
}
}
}
#endregion
}
}
Server code is here:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using RemoteBase;
namespace RemoteServer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
TcpChannel channel;
private void btnStart_Click(object sender, EventArgs e)
{
if (channel == null)
{
channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel, false);
RemotingConfiguration.RegisterWellKnownServiceType(typeof(SampleObject), "HelloWorld", WellKnownObjectMode.Singleton);
lblStatus.Text = "Running...";
btnStart.Enabled = false;
btnStop.Enabled = true;
}
}
private void btnStop_Click(object sender, EventArgs e)
{
if (channel != null)
{
ChannelServices.UnregisterChannel(channel);
channel = null;
lblStatus.Text = "Stopped.";
btnStart.Enabled = true;
btnStop.Enabled = false;
}
}
}
}
Client code is here:
Login and server connecting code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Collections;
using RemoteBase;
namespace RemotingClient
{
public partial class frmLogin : Form
{
TcpChannel chan;
ArrayList alOnlineUser = new ArrayList();
frmChatWin objChatWin;
public frmLogin()
{
InitializeComponent();
}
private void btnJoin_Click(object sender, EventArgs e)
{
JoinToChatRoom();
}
private void JoinToChatRoom()
{
if (chan == null && txtName.Text.Trim().Length != 0)
{
chan = new TcpChannel();
ChannelServices.RegisterChannel(chan,false);
// Create an instance of the remote object
objChatWin = new frmChatWin();
objChatWin.remoteObj = (SampleObject)Activator.GetObject(typeof(RemoteBase.SampleObject), txtServerAdd.Text);
if (!objChatWin.remoteObj.JoinToChatRoom(txtName.Text))
{
MessageBox.Show(txtName.Text+ " already joined, please try with different name");
ChannelServices.UnregisterChannel(chan);
chan = null;
objChatWin.Dispose();
return;
}
objChatWin.key = objChatWin.remoteObj.CurrentKeyNo();
objChatWin.myName= txtName.Text;
this.Hide();
objChatWin.Show();
}
}
}
}
File transferring code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Collections;
using RemoteBase;
using System.IO;
using System.Threading;
namespace RemotingClient
{
public partial class frmChatWin : Form
{
internal SampleObject remoteObj;
internal int key = 0,fileSize;
int sliceSize = 5 * 1024;
internal string myName,fileName;
ArrayList alOnlineUser = new ArrayList();
string selectedUserName;
OpenFileDialog ofd;
public frmChatWin()
{
InitializeComponent();
}
private void btnSend_Click(object sender, EventArgs e)
{
SendFile();
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
if (remoteObj != null)
{
string receiveFileName, senderId;
int fileSize;
string FileName_Size = remoteObj.GetFileName_Size_SenderId(myName);
if (FileName_Size != null)
{
string[] recvFileDesc = FileName_Size.Split(':');
receiveFileName = recvFileDesc[0];
fileSize = int.Parse(recvFileDesc[1]);
senderId = recvFileDesc[2];
DialogResult usrRes = MessageBox.Show(senderId + " want to send a file. Will you accept it?", "", MessageBoxButtons.YesNo);
if (usrRes == DialogResult.Yes)
{
FolderBrowserDialog fbdSelect = new FolderBrowserDialog();
fbdSelect.Description = "Select a path to save received file.";
if (fbdSelect.ShowDialog() == DialogResult.OK)
{
BinaryWriter bWrite = new BinaryWriter(new FileStream(fbdSelect.SelectedPath+"\\" + receiveFileName, FileMode.Append));
for (int i = 0; i * sliceSize <= fileSize; )
{
byte[] buffer = remoteObj.GetDataFromServer(myName, i + 1);//i+1 because when data send to server the it starts from 1
if (buffer != null)
{
bWrite.Write(buffer);
i++;
}
}
bWrite.Close();
remoteObj.ReceiveFileConfirm(myName);
MessageBox.Show("File received successfully.");
}
}
else
{
remoteObj.RejectFile(myName);
}
}
ArrayList onlineUser = remoteObj.GetOnlineUser();
foreach (string name in onlineUser)
{
if (name != myName && !tvOnlineUser.Nodes.ContainsKey(name))
tvOnlineUser.Nodes.Add(name, name);
}
}
//**** Button Enable - Disable
if (tvOnlineUser.Nodes.Count > 0 && lblSelUser.Text.Length > 15)
btnSelect.Enabled = true;
else
btnSelect.Enabled = false;
btnSend.Enabled = false;
if (ofd != null)
if (ofd.FileName.Length > 0)
btnSend.Enabled = true;
timer1.Start();
}
private void SendFile()
{
if (remoteObj != null)
{
BinaryReader bRead = new BinaryReader(new FileStream(ofd.FileName, FileMode.Open));
fileSize = (int)bRead.BaseStream.Length;
if (fileSize > 1024 * 1024 * 50)
MessageBox.Show("You can send maximum 50 MB file.", "Limit cross!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
else
{
byte[] smallPiece;
if (fileSize <>
{
smallPiece = new byte[fileSize];
bRead.Read(smallPiece, 0, fileSize);
}
else//File is more than 5KB
{
smallPiece = new byte[sliceSize];
if (remoteObj.SetFileInfo(myName, selectedUserName, fileName, fileSize))
{
for (int i = 1; i * sliceSize <= fileSize + sliceSize; )
{
if (i * sliceSize <= fileSize) // Last slice yet not reached
{
bRead.Read(smallPiece, 0, sliceSize);
if (remoteObj.SendDataToServer(smallPiece, i, myName))
i++;
}
else//Last slice of data is going to fetch and for last slice data remains less than 5KB
{
int remainDataSize = fileSize - ((i - 1) * sliceSize);
smallPiece = new byte[remainDataSize];
bRead.Read(smallPiece, 0, remainDataSize);
if (remoteObj.SendDataToServer(smallPiece, i, myName))
i++;
}
}
}//End of SetFileInfo
}
}
bRead.Close();
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (remoteObj != null)
{
remoteObj.LeaveChatRoom(myName);
}
Application.Exit();
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("iexplore.exe", "http://socketprogramming.blogspot.com");
}
private void btnSelect_Click(object sender, EventArgs e)
{
ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
lblSelectedFile.Text = "Selected File: "+ofd.SafeFileName;
fileName = ofd.SafeFileName;
}
}
private void tvOnlineUser_DoubleClick(object sender, EventArgs e)
{
selectedUserName = tvOnlineUser.SelectedNode.Name;
lblSelUser.Text = "Selected User: "+selectedUserName;
}
}
}
Labels: c#, client to client, end to end, File Transfer, remoting, user to user

leave a response