Advertisement
Guest User

Untitled

a guest
Dec 9th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.24 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using System.Text;
  8.  
  9. namespace SpeedServer
  10. {
  11.     class Program
  12.     {
  13.         private static int _messageLength = 5;
  14.         private static Stopwatch _tcpTimer = new Stopwatch();
  15.         private static Stopwatch _udpTimer = new Stopwatch();
  16.  
  17.         static async Task Main(string[] args)
  18.         {
  19.             var ipString = "127.0.0.1";
  20.  
  21.  
  22.  
  23.             Task udpTask;
  24.             Task tcpTask;
  25.             using (var tokenSource = new CancellationTokenSource())
  26.             {
  27.                 var token = tokenSource.Token;
  28.                 var udpPortNumber = SetupUdpPortNumber();
  29.                 var tcpPortNumber = SetupTcpPortNumber();
  30.  
  31.  
  32.                 var tcpServer = new TcpListener(IPAddress.Parse(ipString), tcpPortNumber);
  33.                 tcpServer.Start();
  34.                 Console.WriteLine("Tcp server started");
  35.  
  36.                 tcpTask = Task.Run(() => ProcessTcpClients(tcpServer, token), token);
  37.                 udpTask = Task.Run(async () =>
  38.                 {
  39.                     using (var udpClient = new UdpClient(udpPortNumber))
  40.                     {
  41.                         while (!token.IsCancellationRequested)
  42.                         {
  43.                             if (udpClient.Available <= 0)
  44.                             {
  45.                                 continue;
  46.                             }
  47.  
  48.                             _udpTimer.Restart();
  49.                             var data = await ReceiveUdpData(udpClient);
  50.                             var udpMessageLength = data.Length;
  51.                             Console.WriteLine($"Udp Message: {string.Join(", ", data)}");
  52.                             var kilobits = GetBitsAmount(udpMessageLength) / 1000f;
  53.                             var totalSeconds = _udpTimer.Elapsed.TotalSeconds;
  54.                             Console.WriteLine($"Thread UDP: received {kilobits}kb in time {totalSeconds}sec with the speed {kilobits / totalSeconds:F3}kb/sec");
  55.                         }
  56.                     }
  57.  
  58.                     Console.WriteLine("Cancellation token set");
  59.                 }, token);
  60.  
  61.                 while (!Console.KeyAvailable && Console.ReadKey().Key != ConsoleKey.Escape) { };
  62.                 tokenSource.Cancel();
  63.             }
  64.  
  65.             Console.WriteLine("Awaiting tcp");
  66.             await tcpTask;
  67.             Console.WriteLine("Awaiting udp");
  68.             await udpTask;
  69.             //StopServers(tcpServer, udpServer);
  70.         }
  71.  
  72.         private static int SetupUdpPortNumber()
  73.         {
  74.             Console.WriteLine("Send nudes through UDP");
  75.             var readLine = Console.ReadLine();
  76.             readLine = string.IsNullOrEmpty(readLine) ? "333" : readLine;
  77.             var udpPortNumber = int.Parse(readLine);
  78.             Console.WriteLine(udpPortNumber);
  79.             if (udpPortNumber == 333)
  80.             {
  81.                 Console.WriteLine("Using default port 333");
  82.             }
  83.  
  84.             return udpPortNumber;
  85.         }
  86.  
  87.         private static int SetupTcpPortNumber()
  88.         {
  89.             Console.WriteLine("Send nudes through TCP");
  90.             var readLine = Console.ReadLine();
  91.             readLine = string.IsNullOrEmpty(readLine) ? "444" : readLine;
  92.             var tcpPortNumber = int.Parse(readLine);
  93.             if (tcpPortNumber == 444)
  94.             {
  95.                 Console.WriteLine("Using default port 444");
  96.             }
  97.  
  98.             return tcpPortNumber;
  99.         }
  100.  
  101.         private static void StopServers(TcpListener tcpServer, UdpClient udpServer)
  102.         {
  103.             tcpServer.Stop();
  104.  
  105.             udpServer.Close();
  106.             udpServer.Dispose();
  107.         }
  108.  
  109.         private static async Task<byte[]> ReceiveUdpData(UdpClient udpClient)
  110.         {
  111.             return (await udpClient.ReceiveAsync()).Buffer;
  112.         }
  113.  
  114.         private static async Task ProcessTcpClients(TcpListener tcpListener, CancellationToken token)
  115.         {
  116.             var busy = false;
  117.             while (!token.IsCancellationRequested)
  118.             {
  119.                 //Console.WriteLine("Waiting for client");
  120.                 if (tcpListener.Pending())
  121.                 {
  122.                     var client = await tcpListener.AcceptTcpClientAsync();
  123.                     Console.WriteLine("Client connected");
  124.                     if (await RejectIfBusyAsync(busy, client))
  125.                     {
  126.                         Console.WriteLine("Client rejected");
  127.                         continue;
  128.                     }
  129.  
  130.                     Console.WriteLine("Client accepted");
  131.                     busy = true;
  132. #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
  133.                     Task.Run(async () =>
  134.                     {
  135.  
  136.                         try
  137.                         {
  138.                             await HandleClient(client, token);
  139.                         }
  140.                         finally
  141.                         {
  142.                             busy = false;
  143.                             client.Close();
  144.                         }
  145.                     },
  146.                     token);
  147.                 }
  148.             }
  149.         }
  150.  
  151.         private static async Task<bool> RejectIfBusyAsync(bool busy, TcpClient client)
  152.         {
  153.             if (!busy)
  154.             {
  155.                 return false;
  156.             }
  157.  
  158.             using var stream = client.GetStream();
  159.             var busyBytes = Encoding.ASCII.GetBytes("BUSY");
  160.             await stream.WriteAsync(busyBytes);
  161.             return true;
  162.         }
  163.  
  164.         private static async Task HandleClient(TcpClient client, CancellationToken token)
  165.         {
  166.             Console.WriteLine("Getting stream");
  167.             using var stream = client.GetStream();
  168.             Console.WriteLine("Got stream");
  169.             _messageLength = await SetupMessageLengthAsync(client, stream, token);
  170.             await ReadFromClientStream(client, stream, token);
  171.         }
  172.  
  173.         private static async Task<int> SetupMessageLengthAsync(TcpClient client, NetworkStream stream, CancellationToken token)
  174.         {
  175.             var messageFormat = "SIZE:XYZ";
  176.             var sizeMessageLength = messageFormat.Length;
  177.             var buffer = new byte[sizeMessageLength];
  178.             try
  179.             {
  180.                 Console.WriteLine("Reading");
  181.                 await stream.ReadAsync(buffer, 0, sizeMessageLength, token);
  182.                 Console.WriteLine("Finished reading");
  183.                 var messageString = Encoding.ASCII.GetString(buffer);
  184.                 return int.Parse(messageString.Substring(5, 3));
  185.             }
  186.             catch (Exception e)
  187.             {
  188.                 Console.WriteLine(e.Message);
  189.                 stream.Dispose();
  190.                 client.Dispose();
  191.                 return -1;
  192.             }
  193.         }
  194.  
  195.         private static async Task ReadFromClientStream(TcpClient client, NetworkStream stream, CancellationToken token)
  196.         {
  197.             var currentBytesRead = 0;
  198.             do
  199.             {
  200.                 var totalBytesRead = 0;
  201.                 var buffer = new byte[_messageLength];
  202.                 try
  203.                 {
  204.                     _tcpTimer.Restart();
  205.                     do
  206.                     {
  207.                         Console.WriteLine("Reading");
  208.                         currentBytesRead = await stream.ReadAsync(buffer, totalBytesRead, _messageLength - totalBytesRead, token);
  209.                         totalBytesRead += currentBytesRead;
  210.                         if (CloseRequested(buffer))
  211.                         {
  212.                             Cleanup(client, stream);
  213.                             return;
  214.                         }
  215.  
  216.                     } while (totalBytesRead < _messageLength && currentBytesRead != 0);
  217.  
  218.                     Console.WriteLine("Finished reading");
  219.                 }
  220.                 catch (Exception e)
  221.                 {
  222.                     Console.WriteLine(e.Message);
  223.                     Cleanup(client, stream);
  224.                     return;
  225.                 }
  226.  
  227.                 Console.WriteLine($"Message: {string.Join(", ", buffer)}");
  228.                 var kilobits = GetBitsAmount(_messageLength) / 1000f;
  229.                 var totalSeconds = _tcpTimer.Elapsed.TotalSeconds;
  230.                 Console.WriteLine($"Thread TCP: received {kilobits}kb in time {totalSeconds}sec with the speed {kilobits / totalSeconds:F3}kb/sec");
  231.  
  232.             } while (currentBytesRead != 0 && !token.IsCancellationRequested);
  233.         }
  234.  
  235.         private static int GetBitsAmount(int messageLength)
  236.         {
  237.             return (messageLength * 8);
  238.         }
  239.  
  240.         private static void Cleanup(TcpClient client, NetworkStream stream)
  241.         {
  242.             client.Dispose();
  243.             stream.Dispose();
  244.         }
  245.  
  246.         private static bool CloseRequested(byte[] buffer)
  247.         {
  248.             var msgAscii = Encoding.ASCII.GetString(buffer);
  249.             var closeRequested = msgAscii.Contains("FINE");
  250.             if (closeRequested)
  251.             {
  252.                 Console.WriteLine("Close requested by client");
  253.             }
  254.  
  255.             return closeRequested;
  256.         }
  257.     }
  258. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement