//Sender
using System.Net.Sockets;
using System.Security.AccessControl;
namespace ConsoleApp18
{
internal class Program
{
static async Task Main(string[] args)
{
var fileSender = new FileSender();
var progress = new Progress<double>(x => Console.WriteLine($"Progress:{x:F1}"));
bool success = await fileSender.SendFileAsync("127.0.0.1", 8000, @"E:\test.txt", progress);
if(success)
{
Console.WriteLine($"File transfer successfully!");
}
else
{
Console.WriteLine("File transfer failed!");
}
}
}
class FileSender
{
public async Task<bool> SendFileAsync(string serverIp, int port, string filePath,
IProgress<double> progress = null)
{
if(!File.Exists(filePath))
{
Console.WriteLine("File not found!");
return false;
}
TcpClient client = null;
NetworkStream stream = null;
FileStream fileStream = null;
try
{
client = new TcpClient();
await client.ConnectAsync(serverIp, port);
stream = client.GetStream();
FileInfo fileInfo = new FileInfo(filePath);
string fileName = Path.GetFileName(filePath);
byte[] fileNameBytes = System.Text.Encoding.UTF8.GetBytes(fileName);
//Send file name length and file name
await stream.WriteAsync(BitConverter.GetBytes(fileNameBytes.Length), 0, 4);
await stream.WriteAsync(fileNameBytes, 0, fileNameBytes.Length);
//Send file size
await stream.WriteAsync(BitConverter.GetBytes(fileInfo.Length), 0, 8);
//Send file data.
fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[8192];
long totalBytesSent = 0;
int bytesRead;
string tempPercentage = "";
while((bytesRead=await fileStream.ReadAsync(buffer,0,buffer.Length))>0)
{
await stream.WriteAsync(buffer, 0, bytesRead);
totalBytesSent += bytesRead;
//Report progress
double percentage = (double)totalBytesSent / fileInfo.Length * 100;
string newPercentage = $"{percentage:F1}";
if(tempPercentage==newPercentage)
{
continue;
}
Console.WriteLine($"Sending {fileName}:{newPercentage}");
tempPercentage = newPercentage;
progress?.Report(percentage);
}
Console.WriteLine($"File sent successfully:{fileName}");
return true;
}
catch (Exception ex)
{
Console.WriteLine($"Error sending file:{ex.Message}");
return false;
}
finally
{
fileStream?.Close();
stream?.Close();
client?.Close();
}
}
}
}
//Receiver
using System.Net;
using System.Net.Sockets;
namespace ConsoleApp19
{
internal class Program
{
static async Task Main(string[] args)
{
var receiver = new FileReceiver(8000, @"D:\");
await receiver.StartAsync();
}
}
public class FileReceiver
{
private TcpListener listener;
private readonly int port;
private readonly string saveDir;
public FileReceiver(int portValue,string saveDirValue)
{
port = portValue;
saveDir = saveDirValue;
if (!Directory.Exists(saveDir))
{
Directory.CreateDirectory(saveDir);
}
}
public static void GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
Console.WriteLine(ip.ToString());
}
}
}
public async Task StartAsync()
{
listener=new TcpListener(IPAddress.Any,port);
listener.Start();
Console.WriteLine($"Server started on port {port}");
while (true)
{
try
{
var client=await listener.AcceptTcpClientAsync();
_=Task.Run(()=>HandleClientAsync(client));
}
catch (Exception ex)
{
Console.WriteLine($"Error accepting client:{ex.Message}");
}
}
}
private async Task HandleClientAsync(TcpClient client)
{
NetworkStream stream = null;
FileStream fileStream = null;
try
{
stream = client.GetStream();
byte[] buffer = new byte[1024];
int fileNameLength = await ReadIntAsync(stream);
byte[] fileNameBytes=new byte[fileNameLength];
await ReadFullAsync(stream, fileNameBytes, 0,fileNameLength);
string fileName = System.Text.Encoding.UTF8.GetString(fileNameBytes);
long fileSize = await ReadLongAsync(stream);
//
string filePath = Path.Combine(saveDir, fileName);
fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
long totalBytesRead = 0;
int bytesRead;
string tempProgress = "";
while(totalBytesRead<fileSize &&
(bytesRead=await stream.ReadAsync(buffer, 0,
(int)Math.Min(buffer.Length,fileSize-totalBytesRead)))>0)
{
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
//Report progess
double progress = (double)totalBytesRead / fileSize * 100;
string newProgress = $"{progress:F1}";
if(tempProgress==newProgress)
{
continue;
}
Console.WriteLine($"Receiving {fileName}:{newProgress}");
tempProgress = newProgress;
}
Console.WriteLine($"File received :{fileName} ({fileSize}) bytes)");
}
catch (Exception ex)
{
Console.WriteLine($"Error handling client:{ex.Message}");
}
finally
{
fileStream?.Close();
stream?.Close();
client.Close();
}
}
private async Task<long> ReadLongAsync(NetworkStream stream)
{
byte[] buffer = new byte[8];
await ReadFullAsync(stream,buffer,0,8);
return BitConverter.ToInt64(buffer,0);
}
private async Task<int> ReadIntAsync(NetworkStream stream)
{
byte[] buffer = new byte[4];
await ReadFullAsync(stream, buffer, 0, 4);
return BitConverter.ToInt32(buffer, 0);
}
private async Task ReadFullAsync(NetworkStream stream, byte[] buffer, int offset, int count)
{
int totalRead = 0;
while(totalRead< count)
{
int read = await stream.ReadAsync(buffer, offset + totalRead, count - totalRead);
if(read==0)
{
throw new EndOfStreamException();
}
totalRead += read;
}
}
}
}