Hi,
I have a tcp sender that send
large file over tcp.
I have a receiver that receive the files and save them to disk.
It work great for one file,
for multiple files it does not work!
I am googleing a few days, went over almost all articles and did not find a solution.
I would VERY appreciate if someone can help me and make my code run as I need!!!
thanks in advanced!
In the sender , I have a fileSystemWatcher, that watch a folder, and when a file created it takes the file and send it over tcp, by the sender.
Here is the sender code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Sender
{
public class SocketSender
{
#region Memebers
private IPEndPoint targetEndPoint = null;
private bool _isConnected;
Socket clientSock = null;
private ManualResetEvent PauseIfDisconnected;
#endregion
public SocketSender(IPEndPoint ipEndPoint)
{
targetEndPoint= ipEndPoint;
clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_isConnected = false;
PauseIfDisconnected = new ManualResetEvent(_isConnected);
}
public void Connect()
{
try
{
while (true)
{
if (!_isConnected)
{
try
{
clientSock = null;
clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSock.Connect(targetEndPoint);
PauseIfDisconnected.Set();
_isConnected = true;
}
catch (Exception ex)
{
Console.WriteLine("======= ERROR Connect function =====");
Console.WriteLine(ex.ToString());
}
}
else
{
if (!clientSock.Connected)
{
PauseIfDisconnected.Reset();
_isConnected = false;
clientSock.Close();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("======= ERROR Connect function =====");
Console.WriteLine(ex.ToString());
}
}
public void Send(string fileToSend)
{
if (targetEndPoint == null)
return;
Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte[] fileName = Encoding.UTF8.GetBytes(Path.GetFileName(fileToSend));
byte[] fileData = File.ReadAllBytes(fileToSend);
byte[] fileNameLen = BitConverter.GetBytes(fileName.Length);
var clientData = new byte[4 + fileName.Length + fileData.Length];
fileNameLen.CopyTo(clientData, 0);
fileName.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileName.Length);
try
{
clientSock.Connect(targetEndPoint);
clientSock.Send(clientData);
clientSock.Close();
}
catch (Exception ex)
{
Console.WriteLine("======= ERROR Send function =====");
Console.WriteLine(ex.ToString());
}
}
}
}
Her is the receive code (a different project):
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Receiver
{
public class AsynchronousClient
{
#region Members
Thread t1;
int flag = 0;
IPEndPoint ipEnd = null;
string folderSavePath;
public static ManualResetEvent allDone = new ManualResetEvent(false);
#endregion
public AsynchronousClient(IPEndPoint ipEndPoint, string fSavePath)
{
ipEnd = ipEndPoint;
folderSavePath = fSavePath;
t1 = new Thread(new ThreadStart(StartListening));
t1.Start();
}
public void StartListening()
{
if (ipEnd == null)
return;
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(ipEnd);
listener.Listen(100);
while (true)
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
allDone.WaitOne();
}
}
catch (Exception ex)
{
}
}
public void AcceptCallback(IAsyncResult ar)
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
StateObject state = new StateObject();
state.WorkSocket = handler;
handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
flag = 0;
}
string fileSavePath = string.Empty;
public void ReadCallback(IAsyncResult ar)
{
int fileNameLen = 1;
String content = String.Empty;
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.WorkSocket;
int bytesRead = handler.EndReceive(ar);
try
{
if (bytesRead > 0)
{
if (flag == 0)
{
if (!Directory.Exists(folderSavePath))
{
Directory.CreateDirectory(folderSavePath);
}
fileNameLen = BitConverter.ToInt32(state.Buffer, 0);
string fileName = Encoding.UTF8.GetString(state.Buffer, 4, fileNameLen);
fileSavePath = folderSavePath + "\\" + fileName;
flag++;
}
if (flag >= 1)
{
using (BinaryWriter writer = new BinaryWriter(File.Open(fileSavePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)))
{
if (flag == 1)
{
writer.Write(state.Buffer, 4 + fileNameLen, bytesRead - (4 + fileNameLen));
flag++;
}
else
writer.Write(state.Buffer, 0, bytesRead);
writer.Flush();
writer.Close();
}
handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
else
{
handler.Close();
}
}
catch(Exception ex)
{
}
}
}
}
What I have tried:
I tried to develope a tcp sender that send multiple large files over TCP,
and a receiver, that listen and get the files from TCP and save them to disk.