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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| 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 with using 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:
1
2
| var sender = new FileSender();
await sender.SendFileAsync("largefile.zip", "192.168.1.100", 5000);
|
Receiver:
1
2
| 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.