/// <summary> /// Initializes a new instance with the ClientStateObject /// and Exception. /// </summary> /// <param name="stateObj"></param> /// <param name="ex"></param> public TcpDataEventArgs(CallbackStateObject stateObj, Exception ex) { Data = new byte[0]; Length = 0; ClientStateObject = stateObj; Exception = ex; }
/// <summary> /// Initializes a new instance with the data, length /// and ClientStateObject. /// </summary> /// <param name="stateObj">The callback state.</param> /// <param name="data">The data the server received.</param> /// <param name="length">The length of the received data.</param> public TcpDataEventArgs(CallbackStateObject stateObj, byte[] data, int length) { Data = data; Length = length; ClientStateObject = stateObj; Exception = null; }
// Loop for accepting client connections. private void AcceptClientLoop() { try { while (true) { // Start polling _waiter.Reset(); // Create state object for async callback of client. var stateObj = new CallbackStateObject(_listener, null); // Begin accepting client communication. _listener.BeginAcceptTcpClient(EndAcceptClient, stateObj); // Wait until client is processed. _waiter.WaitOne(); } /* Endless loop to connect all clients knocking. */ } catch (SocketException socketEx) { _listener.Stop(); throw new SocketException(socketEx.ErrorCode); } }
/// <summary> /// Closes a client connection and raises events depending /// on various object states. /// </summary> /// <param name="ar"></param> protected virtual void EndAcceptClient(IAsyncResult ar) { // Stores Exception that might occur. Exception ex = null; CallbackStateObject stateObj = ar.AsyncState as CallbackStateObject; if (null == stateObj) { ex = new ArgumentNullException(nameof(ar.AsyncState)); stateObj = new CallbackStateObject(_listener, null); OnDataDropped(new TcpDataEventArgs(stateObj, ex)); return; } /* Invalid CallbackStateObject. */ try { // Get TcpClient from state object. TcpClient client = stateObj.Server.EndAcceptTcpClient(ar); if (null == client) { ex = new ArgumentNullException(nameof(client)); OnDataDropped(new TcpDataEventArgs(stateObj, ex)); return; } /* Invalid TcpClient object. */ NetworkStream stream = client.GetStream(); if (null == stream) { stateObj.Client = client; ex = new ArgumentNullException(nameof(stream)); OnDataDropped(new TcpDataEventArgs(stateObj, ex)); return; } /* No data. */ // Assign buffer for TCP data. byte[] buffer = new byte[0x0100]; // Begin reading the NetworkStream. int length = stream.Read(buffer, 0, buffer.Length); while (0 != length) { // Notify that data has been received. OnDataReceived(new TcpDataEventArgs(buffer, length)); // Continue reading stream. length = stream.Read(buffer, 0, buffer.Length); } /* Loop while stream has data. */ } catch (ArgumentNullException) { ex = new ArgumentNullException(SR.ERROR_BUFFERNULL); } catch (ArgumentOutOfRangeException) { ex = new ArgumentOutOfRangeException(SR.ERROR_OFFSETREAD); } catch (System.IO.IOException) { ex = new System.IO.IOException(SR.ERROR_SOCKETORSTREAM); } catch (ObjectDisposedException) { ex = new ObjectDisposedException(SR.ERROR_STREAMCLOSED); } catch (InvalidOperationException) { ex = new InvalidOperationException(SR.ERROR_READNOTSUPPORTED); } finally { if (null != ex) { OnDataDropped(new TcpDataEventArgs(stateObj, ex)); } /* Exception was caught. */ // Allow next call of EndAcceptClient(). _waiter.Set(); } }