File Transfer in C#
in .NET
This guide demonstrates a reliable file transfer solution using C#'s native networking classes, with enhancements for error handling, asynchronous operations, and large file support.
Enhanced Client Implementation
using System.IO;
using System.Net.Sockets;
using System.Threading.Tasks;
public class FileSender
{
public async Task SendFileAsync(string filePath, string host, int port)
{
using var client = new TcpClient();
await client.ConnectAsync(host, port);
using var networkStream = client.GetStream();
using var fileStream = File.OpenRead(filePath);
// Send file metadata first (file name and size)
var fileName = Path.GetFileName(filePath);
var fileNameData = System.Text.Encoding.UTF8.GetBytes(fileName);
await networkStream.WriteAsync(BitConverter.GetBytes(fileNameData.Length), 0, 4);
await networkStream.WriteAsync(fileNameData, 0, fileNameData.Length);
await networkStream.WriteAsync(BitConverter.GetBytes(fileStream.Length), 0, 8);
// Buffer-based transfer for large files
var buffer = new byte[81920];
int bytesRead;
while ((bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await networkStream.WriteAsync(buffer, 0, bytesRead);
}
}
}
Enhanced Server Implementation
using System.Net.Sockets;
using System.Threading.Tasks;
public class FileReceiver
{
public async Task StartListeningAsync(int port, string saveDirectory)
{
var listener = new TcpListener(System.Net.IPAddress.Any, port);
listener.Start();
try
{
while (true)
{
var client = await listener.AcceptTcpClientAsync();
_ = Task.Run(() => HandleClientAsync(client, saveDirectory));
}
}
finally
{
listener.Stop();
}
}
private async Task HandleClientAsync(TcpClient client, string saveDirectory)
{
using (client)
using (var stream = client.GetStream())
{
// Read metadata
var fileNameSizeBuffer = new byte[4];
await stream.ReadAsync(fileNameSizeBuffer, 0, 4);
int fileNameSize = BitConverter.ToInt32(fileNameSizeBuffer);
var fileNameBuffer = new byte[fileNameSize];
await stream.ReadAsync(fileNameBuffer, 0, fileNameSize);
string fileName = System.Text.Encoding.UTF8.GetString(fileNameBuffer);
var fileSizeBuffer = new byte[8];
await stream.ReadAsync(fileSizeBuffer, 0, 8);
long fileSize = BitConverter.ToInt64(fileSizeBuffer);
// Prepare file storage
var savePath = Path.Combine(saveDirectory, fileName);
using var fileStream = File.Create(savePath);
// Buffer-based reception
var buffer = new byte[81920];
long totalBytesRead = 0;
int bytesRead;
while (totalBytesRead < fileSize &&
(bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
}
}
}
}
Key Enhancements
- Asynchronous Operations
• Uses
async/await
for non-blocking I/O • Handles multiple concurrent connections • Implements proper resource cleanup withusing
statements - Large File Support • Chunked transfer using 80KB buffers (adjustable) • Memory-efficient streaming instead of full-file buffering • Progress tracking capability
- Metadata Handling • Transmits filename and size before file content • UTF-8 encoding for cross-platform compatibility • Prevents path injection attacks
- Error Handling • Automatic client disconnection cleanup • Network timeout handling (recommended to add) • File size validation during transfer
Usage Example
Sender:
var sender = new FileSender();
await sender.SendFileAsync("largefile.zip", "192.168.1.100", 5000);
Receiver:
var receiver = new FileReceiver();
await receiver.StartListeningAsync(5000, @"C:\ReceivedFiles");
Recommended Improvements
- Security Enhancements • Add SSL/TLS encryption • Implement file checksum verification • Add authentication mechanism
- Performance Optimization • Implement compression during transfer • Adjust buffer size based on network conditions • Add parallel chunk transfer support
- Diagnostics • Add transfer progress reporting • Implement cancellation support • Add logging for error tracking
Comparison Table: Native vs Enhanced Implementation
Feature | Basic Implementation | Enhanced Version |
---|---|---|
Large File Support | ❌ | ✅ |
Async Operations | ❌ | ✅ |
Metadata Handling | ❌ | ✅ |
Memory Efficiency | ❌ | ✅ |
Concurrent Connections | ❌ | ✅ |
Error Handling | ❌ | Partial |
This implementation provides a foundation for reliable file transfers while maintaining flexibility for customization. For production use, consider implementing additional security measures and error recovery mechanisms.