Created
October 25, 2018 00:04
-
-
Save kenanhancer/feb0250ea4c8a895dabcefb37eb77fda to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Sockets; | |
using System.Text; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace ConsoleApp6 | |
{ | |
internal class Program | |
{ | |
private const string host = "127.0.0.1"; | |
private const int port = 8080; | |
private const string _sourcePath = @"C:\SourceDir"; | |
private const string _destinationPath = @"C:\TestCopy"; | |
private static int _consoleTop = 1; | |
private static readonly char[] _progressCharacters = @"/-\|".ToArray(); | |
private static void Main(string[] args) | |
{ | |
MainAsync().ConfigureAwait(false).GetAwaiter().GetResult(); | |
} | |
private static async Task MainAsync() | |
{ | |
CancellationTokenSource cts = new CancellationTokenSource(); | |
Console.CancelKeyPress += (s, e) => | |
{ | |
e.Cancel = true; | |
cts.Cancel(); | |
}; | |
if (Directory.Exists(_destinationPath)) | |
{ | |
Directory.Delete(_destinationPath, true); | |
} | |
Directory.CreateDirectory(_destinationPath); | |
Task tcpListenerTask = StartTcpListener(host, port, cts.Token); | |
Task tcpClientTask = StartTcpClient(host, port, cts.Token); | |
await Task.WhenAll(tcpListenerTask, tcpClientTask); | |
} | |
private static async Task StartTcpListener(string ip, int port, CancellationToken token) | |
{ | |
TcpListener tcpListener = new TcpListener(IPAddress.Parse(ip), port); | |
tcpListener.Start(2); | |
TcpClient acceptedTcpClient; | |
string fileName; | |
int receiveBufferSize = 8 * 1024; | |
int bytesRead; | |
long totalBytesRead = 0; | |
byte[] bytesBuffer; | |
string fileNameAndSize; | |
string[] fileNameAndSizeArray; | |
bool firstCall = true; | |
string message; | |
while (!token.IsCancellationRequested) | |
{ | |
try | |
{ | |
acceptedTcpClient = await tcpListener.AcceptTcpClientAsync().ContinueWith(t => t.Result, token); | |
using (NetworkStream networkStream = acceptedTcpClient.GetStream()) | |
{ | |
bytesBuffer = new byte[1024]; | |
bytesRead = await networkStream.ReadAsync(bytesBuffer, 0, 1024, token); | |
fileNameAndSize = Encoding.UTF8.GetString(bytesBuffer, 0, Array.IndexOf(bytesBuffer, (byte)0)); | |
fileNameAndSizeArray = fileNameAndSize.Split('|'); | |
fileName = fileNameAndSizeArray[0]; | |
message = $"Server is receiving bytes from client ({acceptedTcpClient.Client.RemoteEndPoint}) for {fileName} "; | |
int.TryParse(fileNameAndSizeArray[1], out int fileNameBytesCount); | |
int currentTop = Interlocked.Increment(ref _consoleTop); | |
firstCall = true; | |
using (FileStream fileStream = File.OpenWrite(Path.Combine(_destinationPath, fileName))) | |
{ | |
totalBytesRead = 0; | |
bytesBuffer = new byte[receiveBufferSize]; | |
while ((bytesRead = await networkStream.ReadAsync(bytesBuffer, 0, receiveBufferSize, token)) > 0) | |
{ | |
await fileStream.WriteAsync(bytesBuffer, 0, bytesRead, token); | |
totalBytesRead += bytesRead; | |
ShowProgress(firstCall, message, totalBytesRead, fileNameBytesCount, currentTop); | |
firstCall = false; | |
} | |
} | |
} | |
} | |
catch (Exception) | |
{ | |
} | |
} | |
} | |
private static async Task StartTcpClient(string ip, int port, CancellationToken token) | |
{ | |
string[] files = Directory.GetFiles(_sourcePath); | |
FileInfo sourceFi; | |
int sendBufferSize = 8 * 1024; | |
int bytesRead; | |
long totalBytesRead = 0; | |
byte[] bytesBuffer; | |
bool firstCall = true; | |
string message; | |
long fileSize; | |
try | |
{ | |
foreach (string sourceFilePath in files) | |
{ | |
using (TcpClient tcpClient = new TcpClient()) | |
{ | |
await tcpClient.ConnectAsync(IPAddress.Parse(ip), port); | |
using (NetworkStream networkStream = tcpClient.GetStream()) | |
{ | |
sourceFi = new FileInfo(sourceFilePath); | |
message = $"Client ({tcpClient.Client.LocalEndPoint}) is sending bytes to server ({tcpClient.Client.RemoteEndPoint}) for {sourceFi.Name} "; | |
fileSize = sourceFi.Length; | |
totalBytesRead = 0; | |
int currentTop = Interlocked.Increment(ref _consoleTop); | |
bytesBuffer = new byte[1024]; | |
Encoding.UTF8.GetBytes($"{sourceFi.Name}|{sourceFi.Length}").CopyTo(bytesBuffer, 0); | |
await networkStream.WriteAsync(bytesBuffer, 0, 1024, token); | |
firstCall = true; | |
using (FileStream fileStream = sourceFi.OpenRead()) | |
{ | |
bytesBuffer = new byte[sendBufferSize]; | |
while ((bytesRead = await fileStream.ReadAsync(bytesBuffer, 0, sendBufferSize, token)) > 0) | |
{ | |
await networkStream.WriteAsync(bytesBuffer, 0, bytesRead); | |
totalBytesRead += bytesRead; | |
ShowProgress(firstCall, message, totalBytesRead, fileSize, currentTop); | |
firstCall = false; | |
} | |
} | |
} | |
} | |
} | |
} | |
catch (Exception) | |
{ | |
} | |
} | |
private static void ShowProgress(bool firstCall, string message, long processed, long total, int cursorTop) | |
{ | |
long percent = (100 * (processed + 1)) / total; | |
long characterIndex = (percent + 1) & 3; | |
lock (typeof(Console)) | |
{ | |
int msgLenght = message.Length; | |
if (firstCall) | |
{ | |
Console.ForegroundColor = ConsoleColor.White; | |
Console.SetCursorPosition(0, cursorTop); | |
Console.Write(message); | |
} | |
Console.SetCursorPosition(msgLenght, cursorTop); | |
if (percent >= 100) | |
{ | |
percent = 100; | |
Console.ForegroundColor = ConsoleColor.Green; | |
Console.Write($"{percent}% [OK]"); | |
} | |
else | |
{ | |
Console.ForegroundColor = ConsoleColor.Red; | |
Console.Out.Write($"{percent}% [{_progressCharacters[characterIndex]}]"); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment