Skip to content

Commit

Permalink
Test tcp client/server with files
Browse files Browse the repository at this point in the history
  • Loading branch information
cristipufu committed Oct 28, 2024
1 parent d165efd commit eb74aad
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 66 deletions.
82 changes: 49 additions & 33 deletions test/Test.TcpClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,80 @@

class TcpClientApp
{
const int BUFFER_SIZE = 8192; // 8KB buffer size

static async Task Main(string[] args)
{
if (args.Length != 2)
if (args.Length != 3)
{
Console.WriteLine("Usage: TcpClientApp <host> <port>");
Console.WriteLine("Usage: TcpClientApp <server_ip> <port> <save_directory>");
return;
}

string host = args[0];
string serverIp = args[0];
int port = int.Parse(args[1]);
string saveDirectory = args[2];

if (!Directory.Exists(saveDirectory))
{
Directory.CreateDirectory(saveDirectory);
}

using var client = new TcpClient();
try
{
await client.ConnectAsync(host, port);
Console.WriteLine($"Connected to {host}:{port}");
using var client = new TcpClient();
Console.WriteLine($"Connecting to {serverIp}:{port}...");
await client.ConnectAsync(serverIp, port);
Console.WriteLine("Connected to server!");

using NetworkStream stream = client.GetStream();

var sendTask = SendDataAsync(stream);
var receiveTask = ReceiveDataAsync(stream);

await Task.WhenAll(sendTask, receiveTask);
await ReceiveFileAsync(stream, saveDirectory);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}

static async Task SendDataAsync(NetworkStream stream)
static async Task ReceiveFileAsync(NetworkStream stream, string saveDirectory)
{
var random = new Random();
while (true)
{
string message = GenerateRandomString(random, 10);
byte[] buffer = Encoding.UTF8.GetBytes(message);
await stream.WriteAsync(buffer);
Console.WriteLine($"Sent: {message}");
await Task.Delay(1000);
}
}
// Receive file name length
byte[] fileNameLengthBytes = new byte[sizeof(int)];
await stream.ReadAsync(fileNameLengthBytes);
int fileNameLength = BitConverter.ToInt32(fileNameLengthBytes);

static async Task ReceiveDataAsync(NetworkStream stream)
{
var buffer = new byte[1024];
while (true)
// Receive file name
byte[] fileNameBytes = new byte[fileNameLength];
await stream.ReadAsync(fileNameBytes);
string fileName = Encoding.UTF8.GetString(fileNameBytes);

// Receive file size
byte[] fileSizeBytes = new byte[sizeof(long)];
await stream.ReadAsync(fileSizeBytes);
long fileSize = BitConverter.ToInt64(fileSizeBytes);

string filePath = Path.Combine(saveDirectory, fileName);
Console.WriteLine($"Receiving file: {fileName} ({fileSize} bytes)");

// Receive file contents
using var fileStream = File.Create(filePath);
byte[] buffer = new byte[BUFFER_SIZE];
long totalBytesReceived = 0;

while (totalBytesReceived < fileSize)
{
int bytesRead = await stream.ReadAsync(buffer);
if (bytesRead == 0) break;
Console.WriteLine($"Received: {Encoding.UTF8.GetString(buffer, 0, bytesRead)}");

await fileStream.WriteAsync(buffer.AsMemory(0, bytesRead));
totalBytesReceived += bytesRead;

// Report progress
double progress = (double)totalBytesReceived / fileSize * 100;
Console.Write($"\rReceiving: {progress:F2}% ({totalBytesReceived}/{fileSize} bytes)");
}
}

static string GenerateRandomString(Random random, int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
Console.WriteLine("\nFile received successfully!");
Console.WriteLine($"Saved as: {filePath}");
}
}
106 changes: 73 additions & 33 deletions test/Test.TcpServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,36 @@

class TcpServerApp
{
const int BUFFER_SIZE = 8192; // 8KB buffer size

static async Task Main(string[] args)
{
if (args.Length != 1)
if (args.Length != 2)
{
Console.WriteLine("Usage: TcpServerApp <port>");
Console.WriteLine("Usage: TcpServerApp <port> <filepath>");
return;
}

int port = int.Parse(args[0]);
var listener = new TcpListener(IPAddress.Any, port);
string filePath = args[1];

if (!File.Exists(filePath))
{
Console.WriteLine($"File not found: {filePath}");
return;
}

var listener = new TcpListener(IPAddress.Any, port);
try
{
listener.Start();
Console.WriteLine($"Server listening on port {port}");
Console.WriteLine($"Ready to send file: {filePath}");

while (true)
{
TcpClient client = await listener.AcceptTcpClientAsync();
_ = HandleClientAsync(client);
_ = HandleClientAsync(client, filePath);
}
}
catch (Exception ex)
Expand All @@ -36,49 +46,79 @@ static async Task Main(string[] args)
}
}

static async Task HandleClientAsync(TcpClient client)
static async Task HandleClientAsync(TcpClient client, string filePath)
{
Console.WriteLine($"Client connected: {client.Client.RemoteEndPoint}");

using NetworkStream stream = client.GetStream();

var sendDataTask = SendDataAsync(stream);
var receiveDataTask = ReceiveDataAsync(stream);

await Task.WhenAll(sendDataTask, receiveDataTask);
try
{
using NetworkStream stream = client.GetStream();
var sendFileTask = SendFileAsync(stream, filePath);
var receiveDataTask = ReceiveDataAsync(stream);

client.Close();
Console.WriteLine($"Client disconnected: {client.Client.RemoteEndPoint}");
await Task.WhenAll(sendFileTask, receiveDataTask);
}
catch (Exception ex)
{
Console.WriteLine($"Error handling client: {ex.Message}");
}
finally
{
client.Close();
Console.WriteLine($"Client disconnected: {client.Client.RemoteEndPoint}");
}
}

static async Task SendDataAsync(NetworkStream stream)
static async Task SendFileAsync(NetworkStream stream, string filePath)
{
var random = new Random();
while (true)
// First send the file name
string fileName = Path.GetFileName(filePath);
byte[] fileNameBytes = Encoding.UTF8.GetBytes(fileName);
byte[] fileNameLengthBytes = BitConverter.GetBytes(fileNameBytes.Length);
await stream.WriteAsync(fileNameLengthBytes);
await stream.WriteAsync(fileNameBytes);

// Then send the file size
long fileSize = new FileInfo(filePath).Length;
byte[] fileSizeBytes = BitConverter.GetBytes(fileSize);
await stream.WriteAsync(fileSizeBytes);

// Send the file contents
using var fileStream = File.OpenRead(filePath);
byte[] buffer = new byte[BUFFER_SIZE];
long totalBytesSent = 0;
int bytesRead;

while ((bytesRead = await fileStream.ReadAsync(buffer)) > 0)
{
string message = GenerateRandomString(random, 10);
byte[] buffer = Encoding.UTF8.GetBytes(message);
await stream.WriteAsync(buffer);
Console.WriteLine($"Sent: {message}");
await Task.Delay(1000);
await stream.WriteAsync(buffer.AsMemory(0, bytesRead));
totalBytesSent += bytesRead;

// Report progress
double progress = (double)totalBytesSent / fileSize * 100;
Console.Write($"\rSending file: {progress:F2}% ({totalBytesSent}/{fileSize} bytes)");
}

Console.WriteLine("\nFile sent successfully!");
}

static async Task ReceiveDataAsync(NetworkStream stream)
{
var buffer = new byte[1024];
while (true)
var buffer = new byte[BUFFER_SIZE];
try
{
int bytesRead = await stream.ReadAsync(buffer);
if (bytesRead == 0) break;
Console.WriteLine($"Received: {Encoding.UTF8.GetString(buffer, 0, bytesRead)}");
}
}
while (true)
{
int bytesRead = await stream.ReadAsync(buffer);
if (bytesRead == 0) break;

static string GenerateRandomString(Random random, int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
Console.WriteLine($"Received from client: {message}");
}
}
catch (IOException)
{
// Client disconnected
}
}
}

0 comments on commit eb74aad

Please sign in to comment.