Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Net;
- using System.Net.Sockets;
- using System.Linq;
- using System.Text;
- using System.Threading;
- namespace Phurious.Android.Blazr
- {
- /// <summary>
- /// An Asynchronous TCP Server that makes use of system managed threads
- /// and callbacks to stop the server ever locking up.
- /// </summary>
- public class AsyncTcpServer
- {
- /// <summary>
- /// The encoding to use when sending / receiving strings.
- /// </summary>
- public Encoding Encoding { get; set; }
- private TcpListener _tcpListener;
- private List<AsyncTcpClient> _clients;
- /// <summary>
- /// Constructor for a new server using an IPAddress and Port
- /// </summary>
- /// <param name="localaddr">The Local IP Address for the server.</param>
- /// <param name="port">The port for the server.</param>
- public AsyncTcpServer(IPAddress localaddr, int port)
- : this()
- {
- _tcpListener = new TcpListener(localaddr, port);
- }
- /// <summary>
- /// Constructor for a new server using an end point
- /// </summary>
- /// <param name="localEP">The local end point for the server.</param>
- public AsyncTcpServer(IPEndPoint localEP)
- : this()
- {
- _tcpListener = new TcpListener(localEP);
- }
- /// <summary>
- /// Private constructor for the common constructor operations.
- /// </summary>
- private AsyncTcpServer()
- {
- this.Encoding = Encoding.ASCII;
- this._clients = new List<AsyncTcpClient>();
- }
- /// <summary>
- /// An enumerable collection of all the currently connected tcp clients
- /// </summary>
- public IEnumerable<TcpClient> TcpClients
- {
- get
- {
- foreach (AsyncTcpClient client in this._clients)
- {
- yield return client.TcpClient;
- }
- }
- }
- /// <summary>
- /// Starts the TCP Server listening for new clients.
- /// </summary>
- public void Listen()
- {
- this._tcpListener.Start();
- this._tcpListener.BeginAcceptTcpClient(AcceptTcpClientCallback, null);
- }
- /// <summary>
- /// Stops the TCP Server listening for new clients and disconnects
- /// any currently connected clients.
- /// </summary>
- public void StopListening()
- {
- this._tcpListener.Stop();
- lock (this._clients)
- {
- foreach (AsyncTcpClient client in this._clients)
- {
- client.TcpClient.Client.Disconnect(false);
- }
- this._clients.Clear();
- }
- }
- /// <summary>
- /// Writes a string to a given TCP Client
- /// </summary>
- /// <param name="tcpClient">The client to write to</param>
- /// <param name="data">The string to send.</param>
- public void Write(TcpClient tcpClient, String data)
- {
- byte[] bytes = this.Encoding.GetBytes(data);
- Write(tcpClient, bytes);
- }
- /// <summary>
- /// Writes a string to all clients connected.
- /// </summary>
- /// <param name="data">The string to send.</param>
- public void Write(String data)
- {
- foreach (AsyncTcpClient client in this._clients)
- {
- Write(client.TcpClient, data);
- }
- }
- /// <summary>
- /// Writes a byte array to all clients connected.
- /// </summary>
- /// <param name="bytes">The bytes to send.</param>
- public void Write(Byte[] bytes)
- {
- foreach (AsyncTcpClient client in this._clients)
- {
- Write(client.TcpClient, bytes);
- }
- }
- /// <summary>
- /// Writes a byte array to a given TCP Client
- /// </summary>
- /// <param name="tcpClient">The client to write to</param>
- /// <param name="bytes">The bytes to send</param>
- public void Write(TcpClient tcpClient, Byte[] bytes)
- {
- NetworkStream networkStream = tcpClient.GetStream();
- networkStream.BeginWrite(bytes, 0, bytes.Length, WriteCallback, tcpClient);
- }
- public void Write(AsyncTcpClient client, Byte[] bytes)
- {
- NetworkStream networkStream = client.NetworkStream;
- networkStream.BeginWrite(bytes, 0, bytes.Length, WriteCallback, client.TcpClient);
- }
- /// <summary>
- /// Callback for the write opertaion.
- /// </summary>
- /// <param name="result">The async result object</param>
- private void WriteCallback(IAsyncResult result)
- {
- TcpClient tcpClient = result.AsyncState as TcpClient;
- NetworkStream networkStream = tcpClient.GetStream();
- networkStream.EndWrite(result);
- }
- /// <summary>
- /// Callback for the accept tcp client opertaion.
- /// </summary>
- /// <param name="result">The async result object</param>
- private void AcceptTcpClientCallback(IAsyncResult result)
- {
- TcpClient tcpClient = _tcpListener.EndAcceptTcpClient(result);
- byte[] buffer = new byte[tcpClient.ReceiveBufferSize];
- AsyncTcpClient client = new AsyncTcpClient(tcpClient, buffer);
- client.DataReceived += new AsyncTcpClient.DataReceivedHandler(Program.ProcessCommand);
- lock (this._clients)
- {
- this._clients.Add(client);
- }
- NetworkStream networkStream = client.NetworkStream;
- networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
- _tcpListener.BeginAcceptTcpClient(AcceptTcpClientCallback, null);
- }
- /// <summary>
- /// Callback for the read opertaion.
- /// </summary>
- /// <param name="result">The async result object</param>
- private void ReadCallback(IAsyncResult result)
- {
- AsyncTcpClient client = result.AsyncState as AsyncTcpClient;
- if (client == null) return;
- NetworkStream networkStream = client.NetworkStream;
- int read = networkStream.EndRead(result);
- if (read == 0)
- {
- lock (this._clients)
- {
- this._clients.Remove(client);
- return;
- }
- }
- string data = this.Encoding.GetString(client.Buffer, 0, read);
- networkStream.BeginRead(client.Buffer, 0, client.Buffer.Length, ReadCallback, client);
- }
- }
- /// <summary>
- /// Internal class to join the TCP client and buffer together
- /// for easy management in the server
- /// </summary>
- public class AsyncTcpClient
- {
- public delegate void DataReceivedHandler(AsyncTcpClient client);
- public event DataReceivedHandler DataReceived;
- /// <summary>
- /// The encoding to use when sending / receiving strings.
- /// </summary>
- public Encoding Encoding { get; set; }
- private TcpClient _tcpClient = null;
- private Byte[] _buffer = null;
- /// <summary>
- /// Constructor for a new Client
- /// </summary>
- /// <param name="tcpClient">The TCP client</param>
- /// <param name="buffer">The byte array buffer</param>
- public AsyncTcpClient(TcpClient tcpClient, Byte[] buffer)
- : this()
- {
- if (tcpClient == null) throw new ArgumentNullException("tcpClient is null");
- if (buffer == null) throw new ArgumentNullException("Buffer is null");
- this.TcpClient = tcpClient;
- this.Buffer = buffer;
- }
- private AsyncTcpClient()
- {
- this.Encoding = Encoding.ASCII;
- }
- /// <summary>
- /// Gets the TCP Client
- /// </summary>
- public TcpClient TcpClient
- {
- get
- {
- return _tcpClient;
- }
- set
- {
- _tcpClient = value;
- }
- }
- /// <summary>
- /// Gets the Buffer.
- /// </summary>
- public Byte[] Buffer
- {
- get
- {
- return _buffer;
- }
- set
- {
- _buffer = value;
- if (this.DataReceived != null) this.DataReceived(this);
- }
- }
- /// <summary>
- /// Gets the network stream
- /// </summary>
- public NetworkStream NetworkStream
- {
- get
- {
- return TcpClient.GetStream();
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement