I found the C# source file with the asynchronous class for sending large files via socket tcp between server and client. But my application is necessary that client send file for server.
I'm unable to change class AsynchronousClient.cs to receive file of server.
I need help adjusting the client class to send files.
Many thanks.
https://code.msdn.microsoft.com/windowsdesktop/Fixed-size-large-file-dfc3f45d
Client.cs
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
namespace Client
{
public partial class Client : Form
{
#region Constructor
public Client()
{
InitializeComponent();
}
#endregion
#region Button Event
private void btnConnect_Click(object sender, EventArgs e)
{
int port;
IPAddress ipAddress;
if (string.IsNullOrEmpty(tbxAddress.Text) || string.IsNullOrEmpty(tbxPort.Text))
{
MessageBox.Show(this,Properties.Resources.IsEmptyMsg);
return;
}
try
{
ipAddress = IPAddress.Parse(tbxAddress.Text);
}
catch
{
MessageBox.Show(this,Properties.Resources.InvalidAddressMsg);
return;
}
try
{
port = Convert.ToInt32(tbxPort.Text);
}
catch
{
MessageBox.Show(this,Properties.Resources.InvalidPortMsg);
return;
}
if (port < 0 || port > 65535)
{
MessageBox.Show(this, Properties.Resources.InvalidPortMsg);
return;
}
if (string.IsNullOrEmpty(tbxSavePath.Text))
{
MessageBox.Show(this, Properties.Resources.EmptyPath);
return;
}
AsynchronousClient.IpAddress = ipAddress;
AsynchronousClient.Port = port;
AsynchronousClient.FileSavePath = tbxSavePath.Text;
AsynchronousClient.Client = this;
Thread threadClient= new Thread(new ThreadStart(AsynchronousClient.StartClient));
threadClient.IsBackground = true;
threadClient.Start();
btnConnect.Enabled = false;
}
private void btnSavePath_Click(object sender, EventArgs e)
{
FolderBrowserDialog path = new FolderBrowserDialog();
path.ShowDialog();
this.tbxSavePath.Text = path.SelectedPath;
}
#endregion
#region Change the progressBar
public void SetProgressLength(int len)
{
progressBar.Minimum = 0;
progressBar.Maximum = len;
progressBar.Value = 0;
progressBar.Step = 1;
}
public void ProgressChanged()
{
progressBar.PerformStep();
}
#endregion
#region Functions
public void FileReceiveDone()
{
MessageBox.Show(this, Properties.Resources.FileReceivedDoneMsg);
}
public void ConnectDone()
{
MessageBox.Show(this,Properties.Resources.ConnectionMsg);
}
public void EnableConnectButton()
{
btnConnect.Enabled = true;
}
#endregion
}
}
AsynchonousClient.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace Client
{
public static class AsynchronousClient
{
#region Members
private static string fileName;
private static string fileSavePath = "C:/";
private static long fileLen;
private static AutoResetEvent connectDone = new AutoResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
private static bool connected = false;
private delegate void ProgressChangeHandler();
private delegate void FileReceiveDoneHandler();
private delegate void ConnectDoneHandler();
private delegate void EnableConnectButtonHandler();
private delegate void SetProgressLengthHandler(int len);
#endregion
public static IDictionary<Socket, IPEndPoint> ClientsToSend = new Dictionary<Socket, IPEndPoint>();
public static string FileToSend { get; set; }
private const int c_bufferSize = 5242880;
private static int signal;
private static ManualResetEvent allDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private delegate void RemoveItemHandler(string ipAddress);
private delegate void CompleteSendHandler();
public static IList<Socket> Clients = new List<Socket>();
#region Properties
public static Client Client { get; set; }
public static IPAddress IpAddress { get; set; }
public static int Port { get; set; }
public static string FileSavePath
{
get
{
return fileSavePath;
}
set
{
fileSavePath = value.Replace("\\", "/");
}
}
#endregion
#region Functions
public static void StartClient()
{
connected = false;
if (IpAddress == null)
{
MessageBox.Show(Properties.Resources.InvalidAddressMsg);
return;
}
IPEndPoint remoteEP = new IPEndPoint(IpAddress, Port);
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), clientSocket);
connectDone.WaitOne();
if (connected)
{
Receive(clientSocket);
receiveDone.WaitOne();
Client.BeginInvoke(new FileReceiveDoneHandler(Client.FileReceiveDone));
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
else
{
Thread.CurrentThread.Abort();
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
Socket clientSocket = (Socket)ar.AsyncState;
clientSocket.EndConnect(ar);
}
catch
{
MessageBox.Show(Properties.Resources.InvalidConnectionMsg);
Client.BeginInvoke(new EnableConnectButtonHandler(Client.EnableConnectButton));
connectDone.Set();
return;
}
Client.BeginInvoke(new ConnectDoneHandler(Client.ConnectDone));
connected = true;
connectDone.Set();
}
private static void ReceiveFileInfo(Socket clientSocket)
{
byte[] fileNameLenByte = new byte[4];
try
{
clientSocket.Receive(fileNameLenByte);
}
catch
{
if (!clientSocket.Connected)
{
HandleDisconnectException();
}
}
int fileNameLen = BitConverter.ToInt32(fileNameLenByte, 0);
byte[] fileNameByte = new byte[fileNameLen];
try
{
clientSocket.Receive(fileNameByte);
}
catch
{
if (!clientSocket.Connected)
{
HandleDisconnectException();
}
}
fileName = Encoding.ASCII.GetString(fileNameByte, 0, fileNameLen);
fileSavePath = fileSavePath + "/" + fileName;
byte[] fileLenByte = new byte[8];
clientSocket.Receive(fileLenByte);
fileLen = BitConverter.ToInt64(fileLenByte, 0);
}
private static void Receive(Socket clientSocket)
{
StateObject state = new StateObject();
state.WorkSocket = clientSocket;
ReceiveFileInfo(clientSocket);
int progressLen = checked((int)(fileLen / StateObject.BufferSize + 1));
object[] length = new object[1];
length[0] = progressLen;
Client.BeginInvoke(new SetProgressLengthHandler(Client.SetProgressLength), length);
try
{
clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch
{
if (!clientSocket.Connected)
{
HandleDisconnectException();
}
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket clientSocket = state.WorkSocket;
BinaryWriter writer;
int bytesRead = clientSocket.EndReceive(ar);
if (bytesRead > 0)
{
if (!File.Exists(fileSavePath))
{
writer = new BinaryWriter(File.Open(fileSavePath, FileMode.Create));
}
else
{
writer = new BinaryWriter(File.Open(fileSavePath, FileMode.Append));
}
writer.Write(state.Buffer, 0, bytesRead);
writer.Flush();
writer.Close();
Client.BeginInvoke(new ProgressChangeHandler(Client.ProgressChanged));
try
{
clientSocket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch
{
if (!clientSocket.Connected)
{
MessageBox.Show(Properties.Resources.DisconnectMsg);
}
}
}
else
{
receiveDone.Set();
}
}
#endregion
#region Private Functions
private static void HandleDisconnectException()
{
MessageBox.Show(Properties.Resources.DisconnectMsg);
Client.BeginInvoke(new EnableConnectButtonHandler(Client.EnableConnectButton));
Thread.CurrentThread.Abort();
}
#endregion
}
}
Program.cs
using System;
using System.Threading;
using System.Windows.Forms;
namespace Client
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Client());
}
public static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
}
}
}
Server
Server.cs
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
namespace Server
{
public partial class Server : Form
{
private static bool HasStartup = false;
#region Constructor
public Server()
{
InitializeComponent();
}
#endregion
#region Button Event
private void btnStartup_Click(object sender, EventArgs e)
{
if (!HasStartup)
{
try
{
AsynchronousSocketListener.Port = tbxPort.Text;
}
catch(Exception ex)
{
MessageBox.Show(this,ex.Message);
return;
}
AsynchronousSocketListener.Server = this;
Thread listener = new Thread(new ThreadStart(AsynchronousSocketListener.StartListening));
listener.IsBackground = true;
listener.Start();
HasStartup = true;
}
MessageBox.Show(this,Properties.Resources.StartupMsg);
}
private void btnSelectFile_Click(object sender, EventArgs e)
{
openFileDialog.Multiselect = false;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
tbxFile.Text = openFileDialog.FileName;
AsynchronousSocketListener.FileToSend = tbxFile.Text;
}
}
private void btnSend_Click(object sender, EventArgs e)
{
if(lbxServer.SelectedItems.Count == 0)
{
MessageBox.Show(this,Properties.Resources.SelectClientMsg);
return;
}
if (string.IsNullOrEmpty(tbxFile.Text))
{
MessageBox.Show(this,Properties.Resources.EmptyFilePathMsg);
return;
}
if(AsynchronousSocketListener.Clients.Count == 0)
{
MessageBox.Show(this,Properties.Resources.ConnectionMsg);
return;
}
foreach (object item in lbxServer.SelectedItems)
{
foreach (Socket handler in AsynchronousSocketListener.Clients)
{
IPEndPoint ipEndPoint = (IPEndPoint)handler.RemoteEndPoint;
string address = ipEndPoint.ToString();
if (string.Equals(item.ToString(), address, StringComparison.OrdinalIgnoreCase))
{
AsynchronousSocketListener.ClientsToSend.Add(handler,ipEndPoint);
break;
}
}
}
Thread sendThread = new Thread(new ThreadStart(AsynchronousSocketListener.Send));
sendThread.IsBackground = true;
sendThread.Start();
btnSend.Enabled = false;
}
#endregion
#region ListBox item change functions
public void AddClient(IPEndPoint IpEndPoint)
{
lbxServer.BeginUpdate();
lbxServer.Items.Add(IpEndPoint.ToString());
lbxServer.EndUpdate();
}
public void CompleteSend()
{
while (lbxServer.SelectedIndices.Count > 0)
{
lbxServer.Items.RemoveAt(lbxServer.SelectedIndices[0]);
}
btnSend.Enabled = true;
}
public void RemoveItem(string ipAddress)
{
int index = 0;
bool flag = false;
foreach (object item in lbxServer.SelectedItems)
{
if (!string.Equals(item.ToString(), ipAddress, StringComparison.OrdinalIgnoreCase))
{
index++;
}
else
{
flag = true;
break;
}
}
if (flag)
{
lbxServer.Items.RemoveAt(index);
}
}
public void EnableSendButton()
{
btnSend.Enabled = true;
}
#endregion
}
}
AsynchronousSocketListener.cs
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace Server
{
public static class AsynchronousSocketListener
{
#region Constants
private const int c_clientSockets = 100;
private const int c_bufferSize = 5242880;
#endregion
#region Memebers
private static int port;
private static int signal;
private static ManualResetEvent allDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private delegate void AddClientHandler(IPEndPoint IpEndPoint);
private delegate void CompleteSendHandler();
private delegate void RemoveItemHandler(string ipAddress);
private delegate void EnableSendHandler();
#endregion
#region Properties
public static Server Server { get; set; }
public static string Port
{
set
{
try
{
port = Convert.ToInt32(value);
}
catch (FormatException)
{
throw new Exception(Properties.Resources.InvalidPortMsg);
}
catch (OverflowException ex)
{
throw new Exception(ex.Message);
}
if (port < 0 || port > 65535)
{
throw new Exception(Properties.Resources.InvalidPortMsg);
}
}
}
public static string FileToSend { get; set; }
public static IList<Socket> Clients = new List<Socket>();
public static IDictionary<Socket,IPEndPoint> ClientsToSend = new Dictionary<Socket,IPEndPoint>();
#endregion
#region Functions
public static void StartListening()
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
}
catch (SocketException ex)
{
MessageBox.Show(ex.Message);
return;
}
listener.Listen(c_clientSockets);
while (true)
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
allDone.WaitOne();
}
}
private static void AcceptCallback(IAsyncResult ar)
{
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
IPEndPoint ipEndPoint = handler.RemoteEndPoint as IPEndPoint;
if ((ipEndPoint) != null)
{
Server.BeginInvoke(new AddClientHandler(Server.AddClient),ipEndPoint);
}
Clients.Add(handler);
allDone.Set();
}
public static void SendFileInfo()
{
string fileName = FileToSend.Replace("\\", "/");
IList<Socket> closedSockets = new List<Socket>();
IList<String> removedItems = new List<String>();
while (fileName.IndexOf("/") > -1)
{
fileName = fileName.Substring(fileName.IndexOf("/") + 1);
}
FileInfo fileInfo = new FileInfo(FileToSend);
long fileLen = fileInfo.Length;
byte[] fileLenByte = BitConverter.GetBytes(fileLen);
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName);
byte[] clientData = new byte[4 + fileNameByte.Length + 8];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileLenByte.CopyTo(clientData, 4 + fileNameByte.Length);
foreach (KeyValuePair<Socket, IPEndPoint> kvp in ClientsToSend)
{
Socket handler = kvp.Key;
IPEndPoint ipEndPoint = kvp.Value;
try
{
handler.Send(clientData);
}
catch
{
if (!handler.Connected)
{
closedSockets.Add(handler);
removedItems.Add(ipEndPoint.ToString());
}
}
}
RemoveClient(closedSockets);
RemoveClientItem(removedItems);
closedSockets.Clear();
removedItems.Clear();
}
public static void Send()
{
int readBytes = 0;
byte[] buffer = new byte[c_bufferSize];
IList<Socket> closedSockets = new List<Socket>();
IList<String> removedItems = new List<String>();
SendFileInfo();
using (FileStream stream = new FileStream(FileToSend, FileMode.Open))
{
do
{
sendDone.Reset();
signal = 0;
stream.Flush();
readBytes = stream.Read(buffer,0,c_bufferSize);
if (ClientsToSend.Count == 0)
{
sendDone.Set();
}
foreach (KeyValuePair<Socket,IPEndPoint> kvp in ClientsToSend)
{
Socket handler = kvp.Key;
IPEndPoint ipEndPoint = kvp.Value;
try
{
handler.BeginSend(buffer, 0, readBytes, SocketFlags.None, new AsyncCallback(SendCallback), handler);
}
catch
{
if (!handler.Connected)
{
closedSockets.Add(handler);
signal++;
removedItems.Add(ipEndPoint.ToString());
if (signal >= ClientsToSend.Count)
{
sendDone.Set();
}
}
}
}
sendDone.WaitOne();
RemoveClient(closedSockets);
RemoveClientItem(removedItems);
closedSockets.Clear();
removedItems.Clear();
}
while (readBytes > 0);
}
ClientDisconnect();
CompleteSendFile();
}
private static void SendCallback(IAsyncResult ar)
{
lock (Server)
{
Socket handler = null;
try
{
handler = (Socket)ar.AsyncState;
signal++;
int bytesSent = handler.EndSend(ar);
if (bytesSent == 0)
{
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
}
catch (ArgumentException argEx)
{
MessageBox.Show(argEx.Message);
}
catch (SocketException)
{
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
finally
{
if (signal >= ClientsToSend.Count)
{
sendDone.Set();
}
}
}
}
private static void ClientDisconnect()
{
Clients.Clear();
ClientsToSend.Clear();
}
private static void CompleteSendFile()
{
Server.BeginInvoke(new CompleteSendHandler(Server.CompleteSend));
}
private static void RemoveClientItem(IList<String> ipAddressList)
{
foreach (string ipAddress in ipAddressList)
{
Server.BeginInvoke(new RemoveItemHandler(Server.RemoveItem), ipAddress);
}
if (ClientsToSend.Count == 0)
{
Server.BeginInvoke(new EnableSendHandler(Server.EnableSendButton));
}
}
private static void RemoveClient(IList<Socket> listSocket)
{
if (listSocket.Count > 0)
{
foreach (Socket socket in listSocket)
{
Clients.Remove(socket);
ClientsToSend.Remove(socket);
}
}
}
#endregion
}
}
Program.cs
using System;
using System.Windows.Forms;
namespace Server
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Server());
}
}
}
modified 22-Oct-18 12:53pm.
|