Support Copying Files Via Drag 'n' Drop
Reda-Beloued opened this issue · comments
First of all, Thank you so much for this very useful piece of software especially because it is fully written in C#. For months, I was looking for an MVP that does this with no luck! and I was amazed to see this yesterday on HN
One request is, if possible to add copying files from the host PC by dragging and dropping them directly on the "p2p_desktop" window to have them copied to the guest PC (on its desktop or the active app's window)
Hello @Reda-Beloued, thank you very much, yes of course, It would be a very nice feature to add.
We can create a new UdtSocket
for a new connection
to handle the File Transfer
.
I leave a snippet to start/take inspiration from and a simple video on how to enable the drag & drop
on the PictureBox item.
Contributions are welcome :)
Receiver.cs
using System.IO;
using UdtSharp;
namespace p2pconn
{
static class Receiver
{
static internal void Run(UdtSocket connection)
{
using (var netStream = new UdtNetworkStream(connection))
using (var writer = new BinaryWriter(netStream))
using (var reader = new BinaryReader(netStream))
{
string fileName = reader.ReadString();
long size = reader.ReadInt64();
byte[] buffer = new byte[4 * 1024 * 1024];
using (FileStream fileStream = new FileStream(fileName, FileMode.Create))
{
long read = 0;
while (read < size)
{
int toRecv = reader.ReadInt32();
ReadFragment(reader, toRecv, buffer);
fileStream.Write(buffer, 0, toRecv);
read += toRecv;
writer.Write(true);
}
}
}
}
static int ReadFragment(BinaryReader reader, int size, byte[] buffer)
{
int read = 0;
while (read < size)
{
read += reader.Read(buffer, read, size - read);
}
return read;
}
}
}
Sender.cs
using System;
using System.IO;
using UdtSharp;
namespace p2pconn
{
static class Sender
{
static internal void Run(UdtSocket connection, string file, bool logVerbose)
{
using (var netStream = new UdtNetworkStream(connection))
using (var writer = new BinaryWriter(netStream))
using (var reader = new BinaryReader(netStream))
using (var fileReader = new FileStream(file, FileMode.Open, FileAccess.Read))
{
long fileSize = new FileInfo(file).Length;
writer.Write(Path.GetFileName(file));
writer.Write(fileSize);
byte[] buffer = new byte[512 * 1024];
long pos = 0;
while (pos < fileSize)
{
int toSend = buffer.Length < (fileSize - pos)
? buffer.Length
: (int)(fileSize - pos);
fileReader.Read(buffer, 0, toSend);
int iteration = Environment.TickCount;
writer.Write(toSend);
connection.Send(buffer, 0, toSend);
if (!reader.ReadBoolean())
{
Console.WriteLine("Error in transmission");
return;
}
pos += toSend;
if (logVerbose)
{
Console.WriteLine();
Console.WriteLine("Current: {0} / s",
SizeConverter.ConvertToSizeString(toSend / (Environment.TickCount - iteration) * 1000));
}
}
}
}
}
}
SizeConverter.cs
namespace p2pconn
{
internal enum DataSizeUnit
{
Bytes = 1,
KiloBytes = 1024,
MegaBytes = 1024 * 1024,
GigaBytes = 1024 * 1024 * 1024
};
internal static class SizeConverter
{
internal static string ConvertToSizeString(long size)
{
DataSizeUnit totalSizeUnit = SizeConverter.GetSuitableUnit(size);
return string.Format("{0:#0.##} {1}", SizeConverter.ConvertToSize(
size, totalSizeUnit), SizeConverter.GetUnitString(totalSizeUnit));
}
internal static float ConvertToSize(long size, DataSizeUnit unit)
{
return (float)size / (float)unit;
}
static string GetUnitString(DataSizeUnit unit)
{
switch (unit)
{
case DataSizeUnit.Bytes: return "bytes";
case DataSizeUnit.KiloBytes: return "KB";
case DataSizeUnit.MegaBytes: return "MB";
case DataSizeUnit.GigaBytes: return "GB";
}
return string.Empty;
}
static DataSizeUnit GetSuitableUnit(long size)
{
if (size >= 0 && size < (long)DataSizeUnit.KiloBytes)
return DataSizeUnit.Bytes;
else if (size >= (long)DataSizeUnit.KiloBytes && size <= (long)DataSizeUnit.MegaBytes)
return DataSizeUnit.KiloBytes;
else if (size >= (long)DataSizeUnit.MegaBytes && size <= (long)DataSizeUnit.GigaBytes)
return DataSizeUnit.MegaBytes;
else
return DataSizeUnit.GigaBytes;
}
}
}
Hey @miroslavpejic85, I would like to contribute to this issue. I have around 6 months of experience in ASP.NET and C#.