Advertisement
Guest User

C# Code - Async Server

a guest
Feb 21st, 2013
275
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading;
  8.  
  9. namespace Phurious.Android.Blazr
  10. {
  11.     /// <summary>
  12.     /// An Asynchronous TCP Server that makes use of system managed threads
  13.     /// and callbacks to stop the server ever locking up.
  14.     /// </summary>
  15.     public class AsyncTcpServer
  16.     {
  17.         /// <summary>
  18.         /// The encoding to use when sending / receiving strings.
  19.         /// </summary>
  20.         public Encoding Encoding { get; set; }
  21.  
  22.         private TcpListener _tcpListener;
  23.         private List<AsyncTcpClient> _clients;
  24.  
  25.         /// <summary>
  26.         /// Constructor for a new server using an IPAddress and Port
  27.         /// </summary>
  28.         /// <param name="localaddr">The Local IP Address for the server.</param>
  29.         /// <param name="port">The port for the server.</param>
  30.         public AsyncTcpServer(IPAddress localaddr, int port)
  31.             : this()
  32.         {
  33.             _tcpListener = new TcpListener(localaddr, port);
  34.         }
  35.  
  36.         /// <summary>
  37.         /// Constructor for a new server using an end point
  38.         /// </summary>
  39.         /// <param name="localEP">The local end point for the server.</param>
  40.         public AsyncTcpServer(IPEndPoint localEP)
  41.             : this()
  42.         {
  43.             _tcpListener = new TcpListener(localEP);
  44.         }
  45.  
  46.         /// <summary>
  47.         /// Private constructor for the common constructor operations.
  48.         /// </summary>
  49.         private AsyncTcpServer()
  50.         {
  51.             this.Encoding = Encoding.ASCII;
  52.             this._clients = new List<AsyncTcpClient>();
  53.         }
  54.  
  55.         /// <summary>
  56.         /// An enumerable collection of all the currently connected tcp clients
  57.         /// </summary>
  58.         public IEnumerable<TcpClient> TcpClients
  59.         {
  60.             get
  61.             {
  62.                 foreach (AsyncTcpClient client in this._clients)
  63.                 {
  64.                     yield return client.TcpClient;
  65.                 }
  66.             }
  67.         }
  68.  
  69.         /// <summary>
  70.         /// Starts the TCP Server listening for new clients.
  71.         /// </summary>
  72.         public void Listen()
  73.         {
  74.             this._tcpListener.Start();
  75.             this._tcpListener.BeginAcceptTcpClient(AcceptTcpClientCallback, null);
  76.         }
  77.  
  78.  
  79.  
  80.         /// <summary>
  81.         /// Stops the TCP Server listening for new clients and disconnects
  82.         /// any currently connected clients.
  83.         /// </summary>
  84.         public void StopListening()
  85.         {
  86.             this._tcpListener.Stop();
  87.             lock (this._clients)
  88.             {
  89.                 foreach (AsyncTcpClient client in this._clients)
  90.                 {
  91.                     client.TcpClient.Client.Disconnect(false);
  92.                 }
  93.  
  94.                 this._clients.Clear();
  95.             }
  96.         }
  97.  
  98.         /// <summary>
  99.         /// Writes a string to a given TCP Client
  100.         /// </summary>
  101.         /// <param name="tcpClient">The client to write to</param>
  102.         /// <param name="data">The string to send.</param>
  103.         public void Write(TcpClient tcpClient, String data)
  104.         {
  105.             byte[] bytes = this.Encoding.GetBytes(data);
  106.  
  107.             Write(tcpClient, bytes);
  108.         }
  109.  
  110.  
  111.  
  112.         /// <summary>
  113.         /// Writes a string to all clients connected.
  114.         /// </summary>
  115.         /// <param name="data">The string to send.</param>
  116.         public void Write(String data)
  117.         {
  118.             foreach (AsyncTcpClient client in this._clients)
  119.             {
  120.                 Write(client.TcpClient, data);
  121.             }
  122.         }
  123.  
  124.         /// <summary>
  125.         /// Writes a byte array to all clients connected.
  126.         /// </summary>
  127.         /// <param name="bytes">The bytes to send.</param>
  128.         public void Write(Byte[] bytes)
  129.         {
  130.             foreach (AsyncTcpClient client in this._clients)
  131.             {
  132.                 Write(client.TcpClient, bytes);
  133.             }
  134.         }
  135.  
  136.         /// <summary>
  137.         /// Writes a byte array to a given TCP Client
  138.         /// </summary>
  139.         /// <param name="tcpClient">The client to write to</param>
  140.         /// <param name="bytes">The bytes to send</param>
  141.         public void Write(TcpClient tcpClient, Byte[] bytes)
  142.         {
  143.             NetworkStream networkStream = tcpClient.GetStream();
  144.            
  145.             networkStream.BeginWrite(bytes, 0, bytes.Length, WriteCallback, tcpClient);
  146.         }
  147.  
  148.         public void Write(AsyncTcpClient client, Byte[] bytes)
  149.         {
  150.             NetworkStream networkStream = client.NetworkStream;
  151.            
  152.             networkStream.BeginWrite(bytes, 0, bytes.Length, WriteCallback, client.TcpClient);
  153.         }
  154.  
  155.         /// <summary>
  156.         /// Callback for the write opertaion.
  157.         /// </summary>
  158.         /// <param name="result">The async result object</param>
  159.         private void WriteCallback(IAsyncResult result)
  160.         {
  161.             TcpClient tcpClient = result.AsyncState as TcpClient;
  162.             NetworkStream networkStream = tcpClient.GetStream();
  163.  
  164.             networkStream.EndWrite(result);
  165.         }
  166.  
  167.         /// <summary>
  168.         /// Callback for the accept tcp client opertaion.
  169.         /// </summary>
  170.         /// <param name="result">The async result object</param>
  171.         private void AcceptTcpClientCallback(IAsyncResult result)
  172.         {
  173.             TcpClient tcpClient = _tcpListener.EndAcceptTcpClient(result);
  174.             byte[] buffer = new byte[tcpClient.ReceiveBufferSize];
  175.             AsyncTcpClient client = new AsyncTcpClient(tcpClient, buffer);
  176.             client.DataReceived += new AsyncTcpClient.DataReceivedHandler(Program.ProcessCommand);
  177.  
  178.             lock (this._clients)
  179.             {
  180.                 this._clients.Add(client);
  181.             }
  182.  
  183.             NetworkStream networkStream = client.NetworkStream;
  184.  
  185.             networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
  186.  
  187.             _tcpListener.BeginAcceptTcpClient(AcceptTcpClientCallback, null);
  188.         }
  189.  
  190.         /// <summary>
  191.         /// Callback for the read opertaion.
  192.         /// </summary>
  193.         /// <param name="result">The async result object</param>
  194.         private void ReadCallback(IAsyncResult result)
  195.         {
  196.             AsyncTcpClient client = result.AsyncState as AsyncTcpClient;
  197.  
  198.             if (client == null) return;
  199.  
  200.             NetworkStream networkStream = client.NetworkStream;
  201.  
  202.             int read = networkStream.EndRead(result);
  203.  
  204.             if (read == 0)
  205.             {
  206.                 lock (this._clients)
  207.                 {
  208.                     this._clients.Remove(client);
  209.                     return;
  210.                 }
  211.             }
  212.  
  213.             string data = this.Encoding.GetString(client.Buffer, 0, read);
  214.  
  215.             networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
  216.         }
  217.     }
  218.  
  219. /// <summary>
  220.     /// Internal class to join the TCP client and buffer together
  221.     /// for easy management in the server
  222.     /// </summary>
  223.     public class AsyncTcpClient
  224.     {
  225.         public delegate void DataReceivedHandler(AsyncTcpClient client);
  226.         public event DataReceivedHandler DataReceived;
  227.  
  228.         /// <summary>
  229.         /// The encoding to use when sending / receiving strings.
  230.         /// </summary>
  231.         public Encoding Encoding { get; set; }
  232.  
  233.         private TcpClient _tcpClient = null;
  234.         private Byte[] _buffer = null;
  235.  
  236.         /// <summary>
  237.         /// Constructor for a new Client
  238.         /// </summary>
  239.         /// <param name="tcpClient">The TCP client</param>
  240.         /// <param name="buffer">The byte array buffer</param>
  241.         public AsyncTcpClient(TcpClient tcpClient, Byte[] buffer)
  242.             : this()
  243.         {
  244.             if (tcpClient == null) throw new ArgumentNullException("tcpClient is null");
  245.  
  246.             if (buffer == null) throw new ArgumentNullException("Buffer is null");
  247.  
  248.             this.TcpClient = tcpClient;
  249.  
  250.             this.Buffer = buffer;
  251.         }
  252.  
  253.         private AsyncTcpClient()
  254.         {
  255.             this.Encoding = Encoding.ASCII;
  256.         }
  257.  
  258.         /// <summary>
  259.         /// Gets the TCP Client
  260.         /// </summary>
  261.         public TcpClient TcpClient
  262.         {
  263.             get
  264.             {
  265.                 return _tcpClient;
  266.             }
  267.             set
  268.             {
  269.                 _tcpClient = value;
  270.             }
  271.         }
  272.  
  273.         /// <summary>
  274.         /// Gets the Buffer.
  275.         /// </summary>
  276.         public Byte[] Buffer
  277.         {
  278.             get
  279.             {
  280.                 return _buffer;
  281.             }
  282.             set
  283.             {
  284.                 _buffer = value;
  285.                 if (this.DataReceived != null) this.DataReceived(this);
  286.             }
  287.         }
  288.  
  289.  
  290.         /// <summary>
  291.         /// Gets the network stream
  292.         /// </summary>
  293.         public NetworkStream NetworkStream
  294.         {
  295.             get
  296.             {
  297.                 return TcpClient.GetStream();
  298.             }
  299.         }
  300.     }
  301. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement